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),