first commit
diff --git a/openlane/computer/config.json b/openlane/computer/config.json
new file mode 100644
index 0000000..ae2af62
--- /dev/null
+++ b/openlane/computer/config.json
@@ -0,0 +1,50 @@
+{
+ "DESIGN_NAME": "computer",
+ "DESIGN_IS_CORE": 0,
+ "VERILOG_FILES": [
+ "dir::../../verilog/rtl/defines.v",
+ "dir::../../verilog/rtl/jacaranda-8/UART/*.v",
+ "dir::../../verilog/rtl/jacaranda-8/*.v"
+ ],
+ "CLOCK_PERIOD": 500,
+ "CLOCK_PORT": "wb_clk_i",
+ "CLOCK_NET": "wb_clk_i",
+ "FP_SIZING": "absolute",
+ "DIE_AREA": "0 0 1500 1500",
+ "FP_PIN_ORDER_CFG": "dir::pin_order.cfg",
+ "PL_BASIC_PLACEMENT": 0,
+ "PL_TARGET_DENSITY": 0.40,
+ "VDD_NETS": ["vccd1"],
+ "GND_NETS": ["vssd1"],
+ "DIODE_INSERTION_STRATEGY": 4,
+ "RUN_CVC": 1,
+ "ROUTING_CORES": 16,
+ "pdk::sky130*": {
+ "FP_CORE_UTIL": 45,
+ "RT_MAX_LAYER": "met4",
+ "scl::sky130_fd_sc_hd": {
+ "CLOCK_PERIOD": 10
+ },
+ "scl::sky130_fd_sc_hdll": {
+ "CLOCK_PERIOD": 10
+ },
+ "scl::sky130_fd_sc_hs": {
+ "CLOCK_PERIOD": 8
+ },
+ "scl::sky130_fd_sc_ls": {
+ "CLOCK_PERIOD": 10,
+ "SYNTH_MAX_FANOUT": 5
+ },
+ "scl::sky130_fd_sc_ms": {
+ "CLOCK_PERIOD": 10
+ }
+ },
+ "pdk::gf180mcuC": {
+ "STD_CELL_LIBRARY": "gf180mcu_fd_sc_mcu7t5v0",
+ "CLOCK_PERIOD": 24.0,
+ "FP_CORE_UTIL": 40,
+ "RT_MAX_LAYER": "Metal4",
+ "SYNTH_MAX_FANOUT": 4,
+ "PL_TARGET_DENSITY": 0.45
+ }
+}
diff --git a/openlane/computer/config.tcl b/openlane/computer/config.tcl
new file mode 100644
index 0000000..2574945
--- /dev/null
+++ b/openlane/computer/config.tcl
@@ -0,0 +1,78 @@
+# Copyright 2022 cpu-dev
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set ::env(PDK) "gf180mcuC"
+set ::env(STD_CELL_LIBRARY) "gf180mcu_fd_sc_mcu7t5v0"
+
+set script_dir [file dirname [file normalize [info script]]]
+
+set ::env(ROUTING_CORES) 16
+
+set ::env(DESIGN_NAME) computer
+
+set ::env(DESIGN_IS_CORE) 0
+set ::env(GLB_RT_MAXLAYER) 5
+set ::env(FP_PDN_CHECK_NODES) 0
+
+set ::env(VERILOG_FILES) "\
+ $::env(CARAVEL_ROOT)/verilog/rtl/defines.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/UART/UART.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/UART/rx.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/UART/tx.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/alu.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/cpu.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/decoder.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/alu_controller.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/computer.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/data_mem.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/instr_mem.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/main_controller.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/regfile.v \
+ $::env(DESIGN_DIR)/../../verilog/rtl/jacaranda-8/wishbone.v"
+
+#set ::env(EXTRA_GDS_FILES) "\
+# $::env(PDK_ROOT)open_pdks/sky130/custom/sky130_fd_sc_hd/gds/sky130_ef_sc_hd__decap_12.gds"
+
+#set ::env(EXTRA_LEFS) "\
+# $::env(PDK_ROOT)open_pdks/sky130/custom/sky130_fd_sc_hd/lef/sky130_ef_sc_hd__decap_12.lef"
+
+set ::env(CLOCK_PORT) wb_clk_i
+set ::env(CLOCK_NET) wb_clk_i
+set ::env(CLOCK_PERIOD) 500
+
+#set ::env(SYNTH_STRATEGY) "DELAY 2"
+
+set ::env(PL_TARGET_DENSITY) 0.40
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) "0 0 1500 1500"
+#set ::env(FP_CORE_UTIL) 6
+#set ::env(FP_SIZING) relative
+
+#set ::(DECAP_CELL) "sky130_ef_sc_hd__decap_12"
+
+set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) 0
+set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 1
+set ::env(PL_RESIZER_HOLD_SLACK_MARGIN) 0.2
+set ::env(PL_RESIZER_ALLOW_SETUP_VIOS) 1
+set ::env(QUIT_ON_HOLD_VIOLATIONS) 0
+#set ::env(GLB_RT_ADJUSTMENT) 0.30
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+
+set ::env(VDD_NETS) [list {vccd1}]
+set ::env(GND_NETS) [list {vssd1}]
+
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+set ::env(RUN_CVC) 1
diff --git a/openlane/computer/pin_order.cfg b/openlane/computer/pin_order.cfg
new file mode 100644
index 0000000..2fda806
--- /dev/null
+++ b/openlane/computer/pin_order.cfg
@@ -0,0 +1,10 @@
+#BUS_SORT
+
+#S
+wb_.*
+wbs_.*
+la_.*
+irq.*
+
+#N
+io_.*
diff --git a/openlane/user_project_wrapper/config.json b/openlane/user_project_wrapper/config.json
index 22a00ee..81228c7 100644
--- a/openlane/user_project_wrapper/config.json
+++ b/openlane/user_project_wrapper/config.json
@@ -1,14 +1,15 @@
{
"DESIGN_NAME": "user_project_wrapper",
"VERILOG_FILES": ["dir::../../verilog/rtl/defines.v", "dir::../../verilog/rtl/user_project_wrapper.v"],
- "CLOCK_PERIOD": 10,
- "CLOCK_PORT": "user_clock2",
- "CLOCK_NET": "mprj.clk",
- "FP_PDN_MACRO_HOOKS": "mprj vccd1 vssd1 vccd1 vssd1",
+ "CLOCK_PERIOD": 500,
+ "CLOCK_PORT": "computer.wb_clk_i",
+ "CLOCK_NET": "computer.wb_clk_i",
+ "ROUTING_CORES": 16,
+ "FP_PDN_MACRO_HOOKS": "computer vccd1 vssd1 vccd1 vssd1",
"MACRO_PLACEMENT_CFG": "dir::macro.cfg",
- "VERILOG_FILES_BLACKBOX": ["dir::../../verilog/rtl/defines.v", "dir::../../verilog/rtl/user_proj_example.v"],
- "EXTRA_LEFS": "dir::../../lef/user_proj_example.lef",
- "EXTRA_GDS_FILES": "dir::../../gds/user_proj_example.gds",
+ "VERILOG_FILES_BLACKBOX": ["dir::../../verilog/rtl/defines.v", "dir::../../verilog/rtl/jacaranda-8/computer.v"],
+ "EXTRA_LEFS": "dir::../../lef/computer.lef",
+ "EXTRA_GDS_FILES": "dir::../../gds/computer.gds",
"FP_PDN_CHECK_NODES": 0,
"SYNTH_ELABORATE_ONLY": 1,
"PL_RANDOM_GLB_PLACEMENT": 1,
diff --git a/openlane/user_project_wrapper/macro.cfg b/openlane/user_project_wrapper/macro.cfg
index a7365ab..f04c1e6 100644
--- a/openlane/user_project_wrapper/macro.cfg
+++ b/openlane/user_project_wrapper/macro.cfg
@@ -1 +1 @@
-mprj 1175 1690 N
+computer 1175 1690 N
diff --git a/verilog/rtl/jacaranda-8/UART/UART.v b/verilog/rtl/jacaranda-8/UART/UART.v
new file mode 100644
index 0000000..5147b35
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/UART/UART.v
@@ -0,0 +1,68 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// baud rate 115200bps, stop bit 1bit, data 8bit, no parity, no flow control
+
+module UART(
+ input wire clk,
+ input wire reset,
+ 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,
+ input wire [31:0] clk_freq
+);
+
+ parameter BAUD_RATE = 9600;
+ parameter CLK_FREQ = 250000;
+
+ //wire [31:0] clk_count_bit;
+ reg state;
+
+ //assign clk_count_bit = clk_freq / BAUD_RATE;
+ parameter CLK_COUNT = CLK_FREQ / BAUD_RATE;
+
+ always @(negedge clk) begin
+ if(reset) begin
+ state <= 1'b0;
+ int_req <= 1'b0;
+ end else 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
+ 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, reset, tx_en, begin_flag, tx_data, tx, busy_flag, CLK_COUNT);
+ rx rx1(clk, reset, rx_en, rx, rx_data, receive_flag, CLK_COUNT);
+
+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..11ebb80
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/UART/rx.v
@@ -0,0 +1,83 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+module rx(clk, reset, rx_en, rx, data, end_flag, clk_count_bit);
+ input wire clk;
+ input wire reset;
+ input wire rx_en;
+ input wire rx;
+ output reg[7:0] data;
+ output reg end_flag;
+ input wire [31:0] clk_count_bit;
+
+ wire [31:0] clk_begin_to_receive;
+
+ reg[1:0] state;
+ reg[31:0] clk_count;
+ reg[2:0] bit_count;
+ reg[3:0] recent;
+ wire update_flag;
+
+ assign clk_begin_to_receive = clk_count_bit + clk_count_bit / 2 - 4;
+
+ assign update_flag = (state == 2'b01)
+ ? clk_count == clk_begin_to_receive
+ : clk_count == clk_count_bit - 32'd1;
+
+ always @(posedge clk) begin
+ if(reset) begin
+ data <= 8'b0;
+ end_flag <= 1'b0;
+ state <= 2'b0;
+ clk_count <= 32'd0;
+ bit_count <= 3'd0;
+ recent <= 4'b1111;
+ end else 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
+ 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..7142f83
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/UART/tx.v
@@ -0,0 +1,80 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+module tx(clk, reset, tx_en, begin_flag, data, tx, busy_flag, clk_count_bit);
+ input wire clk;
+ input wire reset;
+ input wire tx_en;
+ input wire begin_flag;
+ input wire[7:0] data;
+ output reg tx;
+ output wire busy_flag;
+ input wire [31:0] clk_count_bit;
+
+ reg[1:0] state;
+ reg[31:0] clk_count;
+ reg[2:0] bit_count;
+ wire update_flag;
+
+ assign update_flag = (clk_count == clk_count_bit - 32'd1);
+ assign busy_flag = ~(state == 2'b00);
+
+ always @(posedge clk) begin
+ if(reset) begin
+ clk_count <= 32'd0;
+ bit_count <= 3'd0;
+ state <= 2'b00;
+ tx <= 1'b1;
+ end else 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
+ end
+endmodule
diff --git a/verilog/rtl/jacaranda-8/alu.v b/verilog/rtl/jacaranda-8/alu.v
new file mode 100644
index 0000000..2203dfb
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/alu.v
@@ -0,0 +1,38 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+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);
+ 4'b1000: 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..5d840c3
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/alu_controller.v
@@ -0,0 +1,36 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+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'b0010: alu_control = 4'b1000;
+ 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..f22512f
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/computer.v
@@ -0,0 +1,215 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+`default_nettype none
+
+module computer(
+`ifdef USE_POWER_PINS
+ inout vccd1, // User area 1 1.8V supply
+ inout vssd1, // User area 1 digital ground
+`endif
+ input wb_clk_i,
+ input wb_rst_i,
+ input wbs_stb_i,
+ input wbs_cyc_i,
+ input wbs_we_i,
+ input [3:0] wbs_sel_i,
+ input [31:0] wbs_adr_i,
+ input [31:0] wbs_dat_i,
+ output wbs_ack_o,
+ output [31:0] wbs_dat_o,
+
+ input [127:0] la_data_in,
+ output [127:0] la_data_out,
+ input [127:0] la_oenb,
+
+ input [`MPRJ_IO_PADS-1:0] io_in,
+ output [`MPRJ_IO_PADS-1:0] io_out,
+ output [`MPRJ_IO_PADS-1:0] io_oeb,
+
+ output [2:0] irq
+);
+
+ wire rx;
+ wire tx;
+ assign io_oeb[37:0] = 38'h00_0000_0000;
+
+ // UART - GPIO
+ assign io_out[37] = tx;
+ assign rx = io_in[36];
+
+ 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;
+ wire 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;
+
+ wire [7:0] instr_mem_addr;
+ wire [7:0] instr_mem_data;
+ wire instr_mem_en;
+
+ wire [7:0] wb_instr_req_addr;
+
+ wire [31:0] uart_clk_freq;
+
+ assign instr_mem_addr = reset ? wb_instr_req_addr: pc;
+
+ reg [7:0] gpio_out;
+ wire [7:0] gpio_in;
+
+ assign io_out[35:28] = gpio_out;
+ assign gpio_in = io_out[27:20];
+
+ wire reset;
+
+ assign reset = la_data_in[0];
+
+ wire clock;
+ assign clock = wb_clk_i;
+
+ wishbone wb(.wb_clk_i(wb_clk_i),
+ .wb_rst_i(wb_rst_i),
+ .wbs_stb_i(wbs_stb_i),
+ .wbs_cyc_i(wbs_cyc_i),
+ .wbs_we_i(wbs_we_i),
+ .wbs_sel_i(wbs_sel_i),
+ .wbs_adr_i(wbs_adr_i),
+ .wbs_dat_i(wbs_dat_i),
+ .wbs_ack_o(wbs_ack_o),
+ .wbs_dat_o(wbs_dat_o),
+ .instr_mem_addr(wb_instr_req_addr),
+ .instr_mem_data(instr_mem_data),
+ .instr_mem_en(instr_mem_en),
+ .uart_freq(uart_clk_freq)
+ );
+
+ instr_mem instr_mem(.addr(instr_mem_addr),
+ .w_data(instr_mem_data),
+ .w_en(instr_mem_en),
+ .r_data(instr),
+ .clock(wb_clk_i),
+ .reset(reset));
+
+ cpu cpu(.clock(clock),
+ .reset(reset),
+ .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(reset) begin
+ tx_en <= 1'b0;
+ rx_en <= 1'b0;
+ end else 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(reset) begin
+ tx_data <= 8'b0;
+ end else if(rs_data == 8'd253 && mem_w_en == 1) begin
+ tx_data <= rd_data;
+ end else begin
+ tx_data <= tx_data;
+ end
+ end
+
+ always @(posedge clock) begin
+ if(reset) begin
+ gpio_out <= 8'b0;
+ end else if(rs_data == 8'd251 && mem_w_en == 1) begin
+ gpio_out <= rd_data;
+ end else begin
+ gpio_out <= gpio_out;
+ end
+ end
+
+ assign begin_flag = (rs_data == 8'd253) & (mem_w_en == 1);
+
+ 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
+ : (rs_data == 8'd251) ? gpio_out
+ : (rs_data == 8'd250) ? int_vec
+ : (rs_data == 8'd249) ? gpio_in
+ : _mem_r_data;
+
+ always @(posedge clock) begin
+ if(reset) begin
+ int_en <= 8'b0;
+ end else 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(reset) begin
+ int_vec <= 8'b0;
+ end else 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),
+ .reset(reset),
+ .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),
+ .clk_freq(uart_clk_freq)
+ );
+
+endmodule
diff --git a/verilog/rtl/jacaranda-8/cpu.v b/verilog/rtl/jacaranda-8/cpu.v
new file mode 100644
index 0000000..b4ccebc
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/cpu.v
@@ -0,0 +1,136 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+module cpu(clock, reset, instr, pc, rd_data, rs_data, mem_w_en, mem_r_data, int_req, int_en, int_vec, reg_w_en);
+ input clock;
+ input reset;
+ 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;
+
+ 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;
+
+ wire reg_reg_mem_w_sel;
+ wire reg_alu_w_sel;
+
+ wire [3:0] alu_ctrl;
+ wire [7:0] alu_out;
+
+ wire flag_w_en;
+
+ wire imm_en;
+ wire ih_il_sel;
+
+ 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);
+
+ 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(reset) begin
+ flag <= 0;
+ end else 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(reset) begin
+ intr_en <= 1'b0;
+ end else 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(reset) begin
+ ret_addr <= 8'b0;
+ end else 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(reset) begin
+ _flag <= 1'b0;
+ pc <= 8'b0;
+ end else 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..b7c59e2
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/data_mem.v
@@ -0,0 +1,33 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+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..8e7f5ac
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/decoder.v
@@ -0,0 +1,25 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+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..f8b9897
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/instr_mem.v
@@ -0,0 +1,34 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+module instr_mem(addr, w_data, w_en, r_data, clock, reset);
+ input [7:0] addr;
+ input [7:0] w_data;
+ input w_en;
+ input clock;
+ output [7:0] r_data;
+ input reset;
+
+ reg [7:0] mem[0:255];
+
+ assign r_data = reset ? 8'b0 : 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/main_controller.v b/verilog/rtl/jacaranda-8/main_controller.v
new file mode 100644
index 0000000..43733d3
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/main_controller.v
@@ -0,0 +1,55 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+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..08b22b6
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/regfile.v
@@ -0,0 +1,43 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+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/wishbone.v b/verilog/rtl/jacaranda-8/wishbone.v
new file mode 100644
index 0000000..70bc797
--- /dev/null
+++ b/verilog/rtl/jacaranda-8/wishbone.v
@@ -0,0 +1,88 @@
+// Copyright 2021 cpu-dev
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+module wishbone(
+ input wb_clk_i,
+ input wb_rst_i,
+ input wbs_stb_i,
+ input wbs_cyc_i,
+ input wbs_we_i,
+ input [3:0] wbs_sel_i,
+ input [31:0] wbs_adr_i,
+ input [31:0] wbs_dat_i,
+ output wbs_ack_o,
+ output [31:0] wbs_dat_o,
+
+ output reg [7:0] instr_mem_addr,
+ output reg [7:0] instr_mem_data,
+ output reg instr_mem_en,
+
+ output reg [31:0] uart_freq
+);
+
+parameter IMEM_WRITE = 32'h3000_0000;
+parameter UART_CLK_FREQ = 32'h3000_0004;
+
+wire valid;
+wire we;
+wire [31:0] rdata;
+wire [31:0] wdata;
+wire [31:0] addr;
+wire sel;
+wire reset;
+wire clk;
+reg ready;
+
+assign valid = wbs_cyc_i & wbs_stb_i;
+assign wbs_ack_o = ready;
+assign we = wbs_we_i;
+assign wbs_dat_o = rdata;
+assign wdata = wbs_dat_i;
+assign addr = wbs_adr_i;
+assign sel = wbs_sel_i;
+
+assign reset = wb_rst_i;
+assign clk = wb_clk_i;
+
+always @(posedge clk) begin
+ if(reset) begin
+ ready <= 1'b0;
+ instr_mem_addr <= 8'b0;
+ instr_mem_data <= 8'b0;
+ instr_mem_en <= 1'b0;
+ uart_freq <= 32'd50_000_000;
+ end else begin
+ if(ready) begin
+ ready <= 1'b0;
+ instr_mem_en <= 1'b0;
+ end
+ if (valid && !ready && !we) begin
+ ready <= 1'b1;
+ end else if (valid && !ready && we) begin
+ case(addr)
+ IMEM_WRITE: begin
+ instr_mem_addr <= wdata[15:8];
+ instr_mem_data <= wdata[7:0];
+ instr_mem_en <= 1'b1;
+ end
+ UART_CLK_FREQ: begin
+ uart_freq <= wdata;
+ end
+ endcase
+ ready <= 1'b1;
+ end
+ end
+end
+endmodule
+
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 5ee1cee..1d44c90 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -82,12 +82,12 @@
/* User project is instantiated here */
/*--------------------------------------*/
-user_proj_example mprj (
+//user_proj_example mprj (
+computer computer (
`ifdef USE_POWER_PINS
- .vccd1(vccd1), // User area 1 1.8V power
- .vssd1(vssd1), // User area 1 digital ground
+ .vccd1(vccd1), // User area 1 1.8V power
+ .vssd1(vssd1), // User area 1 digital ground
`endif
-
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),