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