initial commit
diff --git a/verilog/rtl/jacaranda-8/7SEG/bin_dec_decoder.v b/verilog/rtl/jacaranda-8/7SEG/bin_dec_decoder.v new file mode 100644 index 0000000..4ed3a7c --- /dev/null +++ b/verilog/rtl/jacaranda-8/7SEG/bin_dec_decoder.v
@@ -0,0 +1,12 @@ +module bin_dec_decoder(bin_in, dig_3, dig_2, dig_1); + input [7:0] bin_in; + output [3:0] dig_3; + output [3:0] dig_2; + output [3:0] dig_1; + + assign dig_1 = bin_in % 10; + assign dig_2 = (bin_in/10) % 10; + assign dig_3 = (bin_in/100) % 10; + +endmodule +
diff --git a/verilog/rtl/jacaranda-8/7SEG/nanaseg.v b/verilog/rtl/jacaranda-8/7SEG/nanaseg.v new file mode 100644 index 0000000..ffd646d --- /dev/null +++ b/verilog/rtl/jacaranda-8/7SEG/nanaseg.v
@@ -0,0 +1,22 @@ +module nanaseg(bin_in, seg_dig1, seg_dig2, seg_dig3); + input [7:0] bin_in; + output [6:0] seg_dig1; + output [6:0] seg_dig2; + output [6:0] seg_dig3; + + wire [3:0] dig_3; + wire [3:0] dig_2; + wire [3:0] dig_1; + + bin_dec_decoder bin_dec_decoder(.bin_in(bin_in), + .dig_3(dig_3), + .dig_2(dig_2), + .dig_1(dig_1)); + nanaseg_decoder seg3(.dec_in(dig_3), + .nanaseg_out(seg_dig3)); + nanaseg_decoder seg2(.dec_in(dig_2), + .nanaseg_out(seg_dig2)); + nanaseg_decoder seg1(.dec_in(dig_1), + .nanaseg_out(seg_dig1)); +endmodule +
diff --git a/verilog/rtl/jacaranda-8/7SEG/nanaseg_decoder.v b/verilog/rtl/jacaranda-8/7SEG/nanaseg_decoder.v new file mode 100644 index 0000000..66990c0 --- /dev/null +++ b/verilog/rtl/jacaranda-8/7SEG/nanaseg_decoder.v
@@ -0,0 +1,25 @@ +module nanaseg_decoder(dec_in, nanaseg_out); + input [3:0] dec_in; + output [6:0] nanaseg_out; + + assign nanaseg_out = decode(dec_in); + + function [6:0] decode(input [3:0] dec_in); + begin + case(dec_in) + 4'b0000: decode = 7'b1000000; + 4'b0001: decode = 7'b1111001; + 4'b0010: decode = 7'b0100100; + 4'b0011: decode = 7'b0110000; + 4'b0100: decode = 7'b0011001; + 4'b0101: decode = 7'b0010010; + 4'b0110: decode = 7'b0000010; + 4'b0111: decode = 7'b1111000; + 4'b1000: decode = 7'b0000000; + 4'b1001: decode = 7'b0010000; + default: decode = 7'b1111111; + endcase + end + endfunction +endmodule +
diff --git a/verilog/rtl/jacaranda-8/LED/LED4.v b/verilog/rtl/jacaranda-8/LED/LED4.v new file mode 100644 index 0000000..e932458 --- /dev/null +++ b/verilog/rtl/jacaranda-8/LED/LED4.v
@@ -0,0 +1,29 @@ +module LED4(input [7:0] in_data, + input begin_flag, + output reg [7:0] state_reg, + output reg [3:0] out_data, + input clock); + + reg [27:0] delay_cnt = 28'h0000000; + reg [7:0] buffer; + + always @(posedge clock) begin + if(delay_cnt == 28'h0000000 && begin_flag == 1'b0) begin + delay_cnt <= 28'h0000000; + state_reg <= 8'b00000000; + buffer <= in_data; + end else if(delay_cnt == 28'h0000000 && begin_flag == 1'b1) begin + delay_cnt <= delay_cnt + 28'h0000001; + state_reg <= 8'b00000001; + buffer <= in_data; + end else if(delay_cnt != 28'h2faf080) begin + delay_cnt <= delay_cnt + 28'h0000001; + state_reg <= 8'b00000001; + buffer <= buffer; + end else if(delay_cnt == 28'h2faf080) begin + delay_cnt <= 28'h0000000; + state_reg <= 8'b00000001; + out_data <= buffer[3:0]; + end + end +endmodule
diff --git a/verilog/rtl/jacaranda-8/Makefile b/verilog/rtl/jacaranda-8/Makefile new file mode 100644 index 0000000..16648aa --- /dev/null +++ b/verilog/rtl/jacaranda-8/Makefile
@@ -0,0 +1,18 @@ +verilog = alu_controller.v alu.v computer.v cpu.v data_mem.v decoder.v instr_mem.v main_controller.v regfile.v test_bench.v UART/UART.v UART/tx.v UART/rx.v LED/LED4.v 7SEG/bin_dec_decoder.v 7SEG/nanaseg_decoder.v 7SEG/nanaseg.v +output = computer +top = test_bench +wave = wave.vcd + +all: $(verilog) + iverilog -o $(output) -s $(top) $(verilog) + vvp $(output) + +$(wave): + make all + +wave: $(wave) + gtkwave $(wave) & + +clean: + rm $(output) $(wave) +
diff --git a/verilog/rtl/jacaranda-8/UART/UART.v b/verilog/rtl/jacaranda-8/UART/UART.v new file mode 100644 index 0000000..5ba66c6 --- /dev/null +++ b/verilog/rtl/jacaranda-8/UART/UART.v
@@ -0,0 +1,43 @@ +// clock must be 50MHz +// baud rate 115200bps, stop bit 1bit, data 8bit, no parity, no flow control + +module UART( + input wire clk, + input wire tx_en, + input wire rx_en, + input wire begin_flag, + input wire rx, + input wire [7:0] tx_data, + input wire [7:0] access_addr, + input wire reg_w_en, + output wire tx, + output wire[7:0] rx_data, + output wire busy_flag, + output wire receive_flag, + output reg int_req = 1'b0 +); + + reg state = 1'b0; + + always @(negedge clk) begin + if(state == 1'b0) begin //データ待機中 + int_req <= 1'b0; + if(receive_flag == 1'b1) begin + state <= 1'b1; + end else begin + state <= state; + end + end else if(state == 1'b1) begin //データが来たことをCPUに伝える + int_req <= 1'b1; + if(access_addr == 8'd252 && reg_w_en == 1'b1) begin + state <= 1'b0; + end else begin + state <= state; + end + end + end + + tx tx1(clk, tx_en, begin_flag, tx_data, tx, busy_flag); + rx rx1(clk, rx_en, rx, rx_data, receive_flag); + +endmodule
diff --git a/verilog/rtl/jacaranda-8/UART/rx.v b/verilog/rtl/jacaranda-8/UART/rx.v new file mode 100644 index 0000000..9f3efd3 --- /dev/null +++ b/verilog/rtl/jacaranda-8/UART/rx.v
@@ -0,0 +1,59 @@ +module rx(clk, rx_en, rx, data, end_flag); + input wire clk; + input wire rx_en; + input wire rx; + output reg[7:0] data = 8'b00000000; + output reg end_flag = 1'b0; + + parameter CLK_FREQ = 50_000_000; + parameter BAUD_RATE = 115200; + parameter CLK_COUNT_BIT = CLK_FREQ / BAUD_RATE; + parameter CLK_BEGIN_TO_RECEIVE = CLK_COUNT_BIT + CLK_COUNT_BIT / 2 - 4; + + reg[1:0] state = 2'b00; + reg[31:0] clk_count = 32'd0; + reg[2:0] bit_count = 3'd0; + reg[3:0] recent = 4'b1111; + wire update_flag; + + assign update_flag = (state == 2'b01) + ? clk_count == CLK_BEGIN_TO_RECEIVE + : clk_count == CLK_COUNT_BIT - 32'd1; + + always @(posedge clk) begin + case(state) + 2'b00: begin + clk_count <= 32'd0; + bit_count <= 3'd0; + end_flag <= 1'b0; + recent = {recent[2:0], rx}; + state = (recent == 4'b0000) & rx_en ? 2'b01 : state; + end + 2'b01: begin + clk_count <= clk_count + 32'd1; + if(update_flag) begin + state = 2'b11; + clk_count <= 32'd0; + data[2'd0] <= rx; + bit_count <= 3'd1; + end + end + 2'b11: begin + clk_count <= clk_count + 32'd1; + if(update_flag) begin + state <= (bit_count == 3'd7) ? 2'b10 : state; + data[bit_count] <= rx; + bit_count <= bit_count + 3'd1; + clk_count <= 32'd0; + end + end + 2'b10: begin + clk_count <= clk_count + 32'd1; + if(update_flag) begin + state <= 2'b00; + end_flag <= 1'b1; + end + end + endcase + end +endmodule
diff --git a/verilog/rtl/jacaranda-8/UART/tx.v b/verilog/rtl/jacaranda-8/UART/tx.v new file mode 100644 index 0000000..c3d8dda --- /dev/null +++ b/verilog/rtl/jacaranda-8/UART/tx.v
@@ -0,0 +1,61 @@ +module tx(clk, tx_en, begin_flag, data, tx, busy_flag); + input wire clk; + input wire tx_en; + input wire begin_flag; + input wire[7:0] data; + output reg tx = 1'b1; + output wire busy_flag; + + parameter CLK_FREQ = 50_000_000; + parameter BAUD_RATE = 115200; + parameter CLK_COUNT_BIT = CLK_FREQ / BAUD_RATE; + + reg[1:0] state = 2'b00; + reg[31:0] clk_count = 32'd0; + reg[2:0] bit_count = 3'd0; + wire update_flag; + + assign update_flag = (clk_count == CLK_COUNT_BIT - 32'd1); + assign busy_flag = ~(state == 2'b00); + + always @(posedge clk) begin + case(state) + 2'b00: begin + tx <= 1'b1; + clk_count = 32'd0; + bit_count <= 3'd0; + state <= begin_flag & tx_en ? 2'b01 : state; + end + 2'b01: begin + tx <= 1'b0; + clk_count <= clk_count + 32'd1; + if(update_flag) begin + state <= 2'b11; + clk_count <= 32'd0; + end + end + 2'b11: begin + tx <= data[bit_count]; + clk_count <= clk_count + 32'd1; + if(update_flag) begin + state <= (bit_count == 3'd7) ? 2'b10 : state; + bit_count <= bit_count + 3'd1; + clk_count <= 32'd0; + end + end + 2'b10: begin + tx <= 1'b1; + clk_count <= clk_count + 32'd1; + case({update_flag, begin_flag}) + 2'b11: begin + state <= 2'b01; + clk_count <= 32'd0; + bit_count <= 3'd0; + end + 2'b10: state <= 2'b00; + default: state <= state; + endcase + end + endcase + end +endmodule
diff --git a/verilog/rtl/jacaranda-8/alu.v b/verilog/rtl/jacaranda-8/alu.v new file mode 100644 index 0000000..ef2c075 --- /dev/null +++ b/verilog/rtl/jacaranda-8/alu.v
@@ -0,0 +1,23 @@ +module alu(rd, rs, alu_ctrl, alu_out); + input [7:0] rd, rs; + input [3:0] alu_ctrl; + output [7:0] alu_out; + + assign alu_out = execute(rd, rs, alu_ctrl); + + function [7:0] execute(input [7:0] rd, input [7:0] rs, input [3:0] alu_ctrl); + begin + case(alu_ctrl) + 4'b0000: execute = rd + rs; + 4'b0001: execute = rd & rs; + 4'b0010: execute = rd | rs; + 4'b0011: execute = ~rs; + 4'b0100: execute = rd << rs; + 4'b0101: execute = rd >> rs; + 4'b0110: execute = $signed(rd) >>> $signed(rs); + 4'b0111: execute = (rd == rs); + default: execute = 8'b0000_0000; + endcase + end + endfunction +endmodule
diff --git a/verilog/rtl/jacaranda-8/alu_controller.v b/verilog/rtl/jacaranda-8/alu_controller.v new file mode 100644 index 0000000..8b342b2 --- /dev/null +++ b/verilog/rtl/jacaranda-8/alu_controller.v
@@ -0,0 +1,21 @@ +module alu_controller(opcode, alu_ctrl); + input [3:0] opcode; + output [3:0] alu_ctrl; + + assign alu_ctrl = alu_control(opcode); + + function [3:0] alu_control(input [3:0] opcode); + begin + case(opcode) + 4'b0001: alu_control = 4'b0000; + 4'b0011: alu_control = 4'b0001; + 4'b0100: alu_control = 4'b0010; + 4'b0101: alu_control = 4'b0011; + 4'b0110: alu_control = 4'b0100; + 4'b0111: alu_control = 4'b0101; + 4'b1000: alu_control = 4'b0110; + 4'b1001: alu_control = 4'b0111; + endcase + end + endfunction +endmodule
diff --git a/verilog/rtl/jacaranda-8/computer.v b/verilog/rtl/jacaranda-8/computer.v new file mode 100644 index 0000000..3ec5f32 --- /dev/null +++ b/verilog/rtl/jacaranda-8/computer.v
@@ -0,0 +1,144 @@ +module computer( + input clock, + input rx, + output tx, + output [3:0] led_out_data, + output [6:0] seg_out_1, + output [6:0] seg_out_2, + output [6:0] seg_out_3 +); + wire [7:0] instr; + wire [7:0] pc; + wire [7:0] rd_data; + wire [7:0] rs_data; + wire mem_w_en; + wire [7:0] mem_r_data; + wire [7:0] _mem_r_data; + wire busy_flag; + wire receive_flag; + reg tx_en; + reg rx_en; + reg begin_flag; + reg [7:0] tx_data; + wire [7:0] rx_data; + + reg [7:0] int_vec; + reg [7:0] int_en; + + wire int_req; + + wire reg_w_en; + + reg [7:0] led_in_data; + reg led_begin_flag; + wire [7:0] led_state_reg; + + reg [7:0] nanaseg_in_data; + + instr_mem instr_mem(.addr(pc), + .instr(instr)); + + cpu cpu(.clock(clock), + .instr(instr), + .pc(pc), + .rd_data(rd_data), + .rs_data(rs_data), + .mem_w_en(mem_w_en), + .mem_r_data(mem_r_data), + .int_req(int_req), + .int_en(int_en), + .int_vec(int_vec), + .reg_w_en(reg_w_en)); + + always @(posedge clock) begin + if(rs_data == 8'd255 && mem_w_en == 1) begin + tx_en <= rd_data[0]; + rx_en <= rd_data[1]; + end + end + + always @(posedge clock) begin + if(rs_data == 8'd253 && mem_w_en == 1) begin + tx_data <= rd_data; + begin_flag = 1; + end else begin + tx_data <= tx_data; + begin_flag = 0; + end + end + + data_mem data_mem(.addr(rs_data), + .w_data(rd_data), + .w_en(mem_w_en), + .r_data(_mem_r_data), + .clock(clock)); + + assign mem_r_data = (rs_data == 8'd254) ? {6'b0, receive_flag, busy_flag} + : (rs_data == 8'd252) ? rx_data //UART RX + : (rs_data == 8'd250) ? int_vec //割り込みベクタ + : (rs_data == 8'd249) ? led_state_reg + : _mem_r_data; + + always @(posedge clock) begin + if(rs_data == 8'd251 && mem_w_en == 1) begin + led_in_data <= rd_data; + led_begin_flag <= 1'b1; + end else begin + led_in_data <= led_in_data; + led_begin_flag <= 1'b0; + end + end + + always @(posedge clock) begin + if(rs_data == 8'd248 && mem_w_en == 1) begin + nanaseg_in_data <= rd_data; + end else begin + nanaseg_in_data <= nanaseg_in_data; + end + end + + + //割り込み要求が立っている時は割り込み不許可 + always @(posedge clock) begin + if(int_req == 1'b1) begin + int_en <= 8'h00; + end else if(int_req == 1'b0) begin + int_en <= 8'h01; + end + end + + always @(posedge clock) begin + //割り込みベクタの書き込み + if(rs_data == 8'd250 && mem_w_en == 1'b1) begin + int_vec <= rd_data; + end else begin + int_vec <= int_vec; + end + end + + UART UART(.clk(clock), + .tx_en(tx_en), + .rx_en(rx_en), + .begin_flag(begin_flag), + .rx(rx), + .tx_data(tx_data), + .tx(tx), + .rx_data(rx_data), + .busy_flag(busy_flag), + .receive_flag(receive_flag), + .int_req(int_req), + .access_addr(rs_data), + .reg_w_en(reg_w_en)); + + LED4 LED4(.in_data(led_in_data), + .begin_flag(led_begin_flag), + .state_reg(led_state_reg), + .out_data(led_out_data), + .clock(clock)); + + nanaseg nanaseg(.bin_in(nanaseg_in_data), + .seg_dig1(seg_out_1), + .seg_dig2(seg_out_2), + .seg_dig3(seg_out_3)); + +endmodule
diff --git a/verilog/rtl/jacaranda-8/cpu.v b/verilog/rtl/jacaranda-8/cpu.v new file mode 100644 index 0000000..2e7d3f2 --- /dev/null +++ b/verilog/rtl/jacaranda-8/cpu.v
@@ -0,0 +1,129 @@ +module cpu(clock, instr, pc, rd_data, rs_data, mem_w_en, mem_r_data, int_req, int_en, int_vec, reg_w_en); + input clock; + input [7:0] instr; + //割り込み要求線 + input int_req; + //割り込みイネーブル + input [7:0] int_en; + //割り込みベクタ + input [7:0] int_vec; + + output [7:0] pc; + reg [7:0] ret_addr; + //レジスタから読み込んだデータ + output [7:0] rd_data, rs_data; + //メモリにデータを書き込むか + output mem_w_en; + //メモリから読み込んだデータ + input [7:0] mem_r_data; + reg flag; + reg [7:0] pc = 0; + + wire [3:0] opcode; + wire [1:0] rd_a, rd_a_p, rs_a, rs_a_p; + wire [3:0] imm; + + //レジスタにデータを書き込むか + output reg_w_en; + //レジスタに書き込むデータとそのバッファ + wire [7:0] reg_w_data; + wire [7:0] reg_w_data_p; + wire [7:0] reg_w_data_p_p; + wire [7:0] reg_w_imm; + + //レジスタに書き込むデータをレジスタ(0)かメモリ(1)からか選択する + wire reg_reg_mem_w_sel; + //レジスタに書き込むデータをALUからのデータか選択する(1)でALUから(0)でそれ以外 + wire reg_alu_w_sel; + + + //ALUの制御信号 + wire [3:0] alu_ctrl; + //ALUからの出力 + wire [7:0] alu_out; + + //flagに書き込みを行うか + wire flag_w_en; + + //即値ロードの場合のみ(1)になる信号 + wire imm_en; + //ldih(1)かldil(0)かの信号 + wire ih_il_sel; + + //jmp, je実行時に(1)になる信号 + wire jmp_en, je_en; + wire ret; + + reg intr_en = 1'b0; + reg _flag; + + decoder decoder(instr, opcode, rs_a_p, rd_a_p, imm); + + main_controller main_controller(opcode, rd_a_p, reg_w_en, mem_w_en, reg_reg_mem_w_sel, reg_alu_w_sel, flag_w_en, imm_en, ih_il_sel, jmp_en, je_en, ret); + alu_controller alu_controller(opcode, alu_ctrl); + + regfile regfile(rd_a, rs_a, reg_w_data, reg_w_en, rd_data, rs_data, clock, intr_en); + //即値ロード時のみrd_a, rs_aを3に + assign rd_a = imm_en ? 2'b11 : rd_a_p; + assign rs_a = imm_en ? 2'b11 : rs_a_p; + //レジスタに書き込むデータの出元を選択 + assign reg_w_data_p_p = reg_reg_mem_w_sel ? mem_r_data : rs_data; + assign reg_w_data_p = reg_alu_w_sel ? alu_out : reg_w_data_p_p; + assign reg_w_imm = ih_il_sel ? {imm, rs_data[3:0]} : {rs_data[7:4], imm}; + assign reg_w_data = imm_en ? reg_w_imm : reg_w_data_p; + + alu alu(rd_data, rs_data, alu_ctrl, alu_out); + //フラグレジスタ書き込み + always @(posedge clock) begin + if(ret) begin + flag <= _flag; + end else if(je_en) begin + flag <= 0; + end else if(flag_w_en) begin + flag <= alu_out; + end else begin + flag <= flag; + end + end + + always @(posedge clock) begin + if(ret) begin + intr_en <= 1'b0; + end else if(int_req && int_en[0]) begin + intr_en <= 1'b1; + end + end + + always @(posedge clock) begin + if(int_req == 1'b1 && int_en[0]) begin + if(jmp_en) begin + ret_addr <= rs_data; + end else if(je_en && flag) begin + ret_addr <= rs_data; + end else begin + ret_addr <= pc + 1; + end + end else begin + ret_addr <= ret_addr; + end + end + + always @(posedge clock) begin + if(int_req && int_en[0]) begin + _flag <= flag; + pc <= int_vec; + end else if(ret) begin + pc <= ret_addr; + end else if(jmp_en) begin + pc <= rs_data; + end else if(je_en) begin + if(flag) begin + pc <= rs_data; + end else begin + pc <= pc + 1; + end + end else begin + pc <= pc + 1; + end + end +endmodule
diff --git a/verilog/rtl/jacaranda-8/data_mem.v b/verilog/rtl/jacaranda-8/data_mem.v new file mode 100644 index 0000000..e04c25a --- /dev/null +++ b/verilog/rtl/jacaranda-8/data_mem.v
@@ -0,0 +1,19 @@ +module data_mem(addr, w_data, w_en, r_data, clock); + input [7:0] addr; + input [7:0] w_data; + input w_en; + input clock; + output [7:0] r_data; + + reg [7:0] mem[0:255]; + + assign r_data = mem[addr]; + + always @(posedge clock) begin + if(w_en) begin + mem[addr] <= w_data; + end else begin + mem[addr] <= mem[addr]; + end + end +endmodule
diff --git a/verilog/rtl/jacaranda-8/decoder.v b/verilog/rtl/jacaranda-8/decoder.v new file mode 100644 index 0000000..69c15e7 --- /dev/null +++ b/verilog/rtl/jacaranda-8/decoder.v
@@ -0,0 +1,11 @@ +module decoder(instr, opcode, rs_a, rd_a, imm); + input [7:0] instr; + output [3:0] opcode; + output [1:0] rs_a, rd_a; + output [3:0] imm; + + assign opcode = instr[7:4]; + assign rd_a = instr[3:2]; + assign rs_a = instr[1:0]; + assign imm = instr[3:0]; +endmodule
diff --git a/verilog/rtl/jacaranda-8/instr_mem.v b/verilog/rtl/jacaranda-8/instr_mem.v new file mode 100644 index 0000000..4acb0eb --- /dev/null +++ b/verilog/rtl/jacaranda-8/instr_mem.v
@@ -0,0 +1,92 @@ +module instr_mem(addr, instr); + input [7:0] addr; + output [7:0] instr; + + reg [7:0] mem[0:255]; + + assign instr = mem[addr]; + + initial begin + mem[0] = 8'hc0; + mem[1] = 8'hd7; + mem[2] = 8'h03; + mem[3] = 8'hc0; + mem[4] = 8'hd0; + mem[5] = 8'hf3; + mem[6] = 8'h03; + mem[7] = 8'hcf; + mem[8] = 8'hd8; + mem[9] = 8'hf3; + mem[10] = 8'hc0; + mem[11] = 8'hd1; + mem[12] = 8'h07; + mem[13] = 8'h0b; + mem[14] = 8'hc0; + mem[15] = 8'hd0; + mem[16] = 8'hef; + mem[17] = 8'h93; + mem[18] = 8'hc2; + mem[19] = 8'hd1; + mem[20] = 8'ha3; + mem[21] = 8'h16; + mem[22] = 8'hcf; + mem[23] = 8'hd8; + mem[24] = 8'hf7; + mem[25] = 8'h06; + mem[26] = 8'heb; + mem[27] = 8'hc0; + mem[28] = 8'hd1; + mem[29] = 8'h13; + mem[30] = 8'hc0; + mem[31] = 8'hde; + mem[32] = 8'hb3; + mem[33] = 8'hc2; + mem[34] = 8'hd3; + mem[35] = 8'hb3; + +/* + mem[0] = 8'hc0; + mem[1] = 8'hd7; + mem[2] = 8'h03; + mem[3] = 8'hc0; + mem[4] = 8'hd0; + mem[5] = 8'hf3; + mem[6] = 8'h03; + mem[7] = 8'hd1; + mem[8] = 8'hf3; + mem[9] = 8'hc0; + mem[10] = 8'hd1; + mem[11] = 8'h07; + mem[12] = 8'h0b; + mem[13] = 8'hc0; + mem[14] = 8'hd0; + mem[15] = 8'hef; + mem[16] = 8'h93; + mem[17] = 8'hc1; + mem[18] = 8'hde; + mem[19] = 8'ha3; + mem[20] = 8'h16; + mem[21] = 8'hc0; //追加 + mem[22] = 8'hd1; + mem[23] = 8'hf7; + mem[24] = 8'h06; + mem[25] = 8'heb; + mem[26] = 8'h13; + mem[27] = 8'hc0; + mem[28] = 8'hdd; + mem[29] = 8'hb3; + mem[30] = 8'h00; + mem[31] = 8'hc1; + mem[32] = 8'hde; + mem[33] = 8'hb3; +*/ + end +endmodule + + + + + + + +
diff --git a/verilog/rtl/jacaranda-8/main_controller.v b/verilog/rtl/jacaranda-8/main_controller.v new file mode 100644 index 0000000..cf5ad08 --- /dev/null +++ b/verilog/rtl/jacaranda-8/main_controller.v
@@ -0,0 +1,41 @@ +module main_controller(opcode, rd_a, reg_w_en, mem_w_en, reg_reg_mem_w_sel, reg_alu_w_sel, flag_w_en, imm_en, ih_il_sel, jmp_en, je_en, ret); + input [3:0] opcode; + input [1:0] rd_a; + output reg_w_en, mem_w_en; + output reg_reg_mem_w_sel; + output reg_alu_w_sel; + output flag_w_en; + output imm_en; + output ih_il_sel; + output jmp_en, je_en; + output ret; + + assign {reg_w_en, mem_w_en, reg_reg_mem_w_sel, reg_alu_w_sel, flag_w_en, imm_en, ih_il_sel, jmp_en, je_en, ret} = main_control(opcode, rd_a); + + function [9:0] main_control(input [3:0] opcode, input [1:0] rd_a); + begin + case(opcode) + 4'b0000: main_control = 10'b1000000000; //mov + 4'b0001: main_control = 10'b1001000000; //add + 4'b0011: main_control = 10'b1001000000; //and + 4'b0100: main_control = 10'b1001000000; //or + 4'b0101: main_control = 10'b1001000000; //not + 4'b0110: main_control = 10'b1001000000; //sll + 4'b0111: main_control = 10'b1001000000; //srl + 4'b1000: main_control = 10'b1001000000; //sra + 4'b1001: main_control = 10'b0001100000; //cmp + 4'b1010: main_control = 10'b0000000010; //je + 4'b1011: begin + case(rd_a) + 2'b01: main_control = 10'b0000000001; //iret + default: main_control = 10'b0000000100; //jmp + endcase + end + 4'b1100: main_control = 10'b1000011000; //ldih + 4'b1101: main_control = 10'b1000010000; //ldil + 4'b1110: main_control = 10'b1010000000; //ld + 4'b1111: main_control = 10'b0100000000; //st + endcase + end + endfunction +endmodule
diff --git a/verilog/rtl/jacaranda-8/regfile.v b/verilog/rtl/jacaranda-8/regfile.v new file mode 100644 index 0000000..d93104c --- /dev/null +++ b/verilog/rtl/jacaranda-8/regfile.v
@@ -0,0 +1,29 @@ +module regfile(rd_addr, rs_addr, w_data, w_en, rd_data, rs_data, clock, intr_en); + input [1:0] rd_addr, rs_addr; + input [7:0] w_data; + input w_en; + input clock; + input intr_en; + output [7:0] rs_data, rd_data; + + reg [7:0] register[0:3]; + reg [7:0] intr_register[0:3]; + + assign rd_data = intr_en ? intr_register[rd_addr] : register[rd_addr]; + assign rs_data = intr_en ? intr_register[rs_addr] : register[rs_addr]; + always @(posedge clock) begin + if(intr_en) begin + if(w_en == 1) begin + intr_register[rd_addr] <= w_data; + end else begin + intr_register[rd_addr] <= intr_register[rd_addr]; + end + end else begin + if(w_en == 1) begin + register[rd_addr] <= w_data; + end else begin + register[rd_addr] <= register[rd_addr]; + end + end + end +endmodule
diff --git a/verilog/rtl/jacaranda-8/test_bench.v b/verilog/rtl/jacaranda-8/test_bench.v new file mode 100644 index 0000000..7bfd58e --- /dev/null +++ b/verilog/rtl/jacaranda-8/test_bench.v
@@ -0,0 +1,161 @@ +`timescale 1ns/1ps +module test_bench(); +parameter TIMESCALE_HZ = 1000_000_000; +parameter CLOCK_HZ = 50_000_000; +parameter BAUD_RATE = 115200; +parameter TIME_CLOCK = $floor(TIMESCALE_HZ / CLOCK_HZ); +parameter TIME_BIT = $floor(TIMESCALE_HZ / BAUD_RATE); + reg clk; + reg rx; + wire[7:0] data; + wire end_flag; + wire [3:0] led_out_data; + wire [6:0] seg_out_1; + wire [6:0] seg_out_2; + wire [6:0] seg_out_3; + computer cmptr(clk, rx, tx, led_out_data, seg_out_1, seg_out_2, seg_out_3); + +always #(TIME_CLOCK/2) clk = ~clk; + +initial begin + $dumpfile("wave.vcd"); + $dumpvars(0, cmptr); + clk = 1'b0; + rx = 1'b1; + #1000 + #(2*TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx= 1'b1; + #(2*TIME_BIT); + #10000 + #1000 + #(2*TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx= 1'b1; + #(2*TIME_BIT); + #1000 + #(2*TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx= 1'b1; + #(2*TIME_BIT); + #1000 + #(2*TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx= 1'b1; + #(2*TIME_BIT); + #1000 + #(2*TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx= 1'b1; + #(2*TIME_BIT); + #1000 + #(2*TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx = 1'b0; + #(TIME_BIT); + rx = 1'b1; + #(TIME_BIT); + rx= 1'b1; + #(2*TIME_BIT); + #100000 + $finish; +end +endmodule