diff --git a/fpga/constrs/tinyriscv.xdc b/fpga/constrs/tinyriscv.xdc index 2473eb4..edf7154 100644 --- a/fpga/constrs/tinyriscv.xdc +++ b/fpga/constrs/tinyriscv.xdc @@ -7,16 +7,8 @@ set_property IOSTANDARD LVCMOS33 [get_ports clk] set_property PACKAGE_PIN N14 [get_ports clk] # 复位引脚 -set_property IOSTANDARD LVCMOS33 [get_ports rst_n] -set_property PACKAGE_PIN L13 [get_ports rst_n] - -# 程序执行完毕指示引脚 -set_property IOSTANDARD LVCMOS33 [get_ports over] -set_property PACKAGE_PIN M16 [get_ports over] - -# 程序执行成功指示引脚 -set_property IOSTANDARD LVCMOS33 [get_ports succ] -set_property PACKAGE_PIN N16 [get_ports succ] +set_property IOSTANDARD LVCMOS33 [get_ports rst_ext_i] +set_property PACKAGE_PIN L13 [get_ports rst_ext_i] # CPU停住指示引脚 set_property IOSTANDARD LVCMOS33 [get_ports halted_ind] diff --git a/rtl/core/exu_alu_datapath.v b/rtl/core/exu_alu_datapath.v index ce96a01..1e03e81 100644 --- a/rtl/core/exu_alu_datapath.v +++ b/rtl/core/exu_alu_datapath.v @@ -128,15 +128,23 @@ module exu_alu_datapath( wire[31:0] slt_res = (~op1_ge_op2_signed)? 32'h1: 32'h0; wire[31:0] sltu_res = (~op1_ge_op2_unsigned)? 32'h1: 32'h0; - wire[31:0] alu_datapath_res = ({32{op_xor}} & xor_res) | - ({32{op_or}} & or_res) | - ({32{op_and}} & and_res) | - ({32{op_add | op_sub}} & add_sub_res) | - ({32{op_sll}} & sll_res) | - ({32{op_srl}} & srl_res) | - ({32{op_sra}} & sra_res) | - ({32{op_slt}} & slt_res) | - ({32{op_sltu}} & sltu_res); + reg[31:0] alu_datapath_res; + + always @ (*) begin + alu_datapath_res = 32'h0; + case (1'b1) + op_xor: alu_datapath_res = xor_res; + op_or: alu_datapath_res = or_res; + op_and: alu_datapath_res = and_res; + op_add: alu_datapath_res = add_sub_res; + op_sub: alu_datapath_res = add_sub_res; + op_sll: alu_datapath_res = sll_res; + op_srl: alu_datapath_res = srl_res; + op_sra: alu_datapath_res = sra_res; + op_slt: alu_datapath_res = slt_res; + op_sltu: alu_datapath_res = sltu_res; + endcase + end assign alu_res_o = alu_datapath_res; diff --git a/rtl/core/exu_commit.v b/rtl/core/exu_commit.v index 5353b1a..e69893d 100644 --- a/rtl/core/exu_commit.v +++ b/rtl/core/exu_commit.v @@ -59,16 +59,34 @@ module exu_commit( assign reg_we_o = muldiv_reg_we_i | mem_reg_we_i | csr_reg_we_i | use_alu_res | bjp_reg_we_i; - assign reg_waddr_o = ({5{muldiv_reg_we_i}} & muldiv_reg_waddr_i) | - ({5{mem_reg_we_i}} & mem_reg_waddr_i) | - ({5{csr_reg_we_i}} & csr_reg_waddr_i) | - ({5{bjp_reg_we_i}} & bjp_reg_waddr_i) | - ({5{rd_we_i}} & rd_waddr_i); + reg[4:0] reg_waddr; - assign reg_wdata_o = ({32{muldiv_reg_we_i}} & muldiv_reg_wdata_i) | - ({32{mem_reg_we_i}} & mem_reg_wdata_i) | - ({32{csr_reg_we_i}} & csr_reg_wdata_i) | - ({32{bjp_reg_we_i}} & bjp_reg_wdata_i) | - ({32{use_alu_res}} & alu_reg_wdata_i); + always @ (*) begin + reg_waddr = 5'h0; + case (1'b1) + muldiv_reg_we_i: reg_waddr = muldiv_reg_waddr_i; + mem_reg_we_i: reg_waddr = mem_reg_waddr_i; + csr_reg_we_i: reg_waddr = csr_reg_waddr_i; + bjp_reg_we_i: reg_waddr = bjp_reg_waddr_i; + rd_we_i: reg_waddr = rd_waddr_i; + endcase + end + + assign reg_waddr_o = reg_waddr; + + reg[31:0] reg_wdata; + + always @ (*) begin + reg_wdata = 32'h0; + case (1'b1) + muldiv_reg_we_i: reg_wdata = muldiv_reg_wdata_i; + mem_reg_we_i: reg_wdata = mem_reg_wdata_i; + csr_reg_we_i: reg_wdata = csr_reg_wdata_i; + bjp_reg_we_i: reg_wdata = bjp_reg_wdata_i; + use_alu_res: reg_wdata = alu_reg_wdata_i; + endcase + end + + assign reg_wdata_o = reg_wdata; endmodule diff --git a/rtl/core/exu_mem.v b/rtl/core/exu_mem.v index 2c69a04..d46e30f 100644 --- a/rtl/core/exu_mem.v +++ b/rtl/core/exu_mem.v @@ -61,36 +61,71 @@ module exu_mem( assign mem_sel_o[2] = mem_addr_index10 | mem_op_sw_i; assign mem_sel_o[3] = mem_addr_index11 | (mem_op_sh_i & mem_addr_index10) | mem_op_sw_i; - // store操作 - wire[31:0] sb_res = ({32{mem_addr_index00}} & {24'h0, mem_rs2_data_i[7:0]}) | - ({32{mem_addr_index01}} & {16'h0, mem_rs2_data_i[7:0], 8'h0}) | - ({32{mem_addr_index10}} & {8'h0, mem_rs2_data_i[7:0], 16'h0}) | - ({32{mem_addr_index11}} & {mem_rs2_data_i[7:0], 24'h0}); + reg[31:0] sb_res; - wire[31:0] sh_res = ({32{mem_addr_index00}} & {16'h0, mem_rs2_data_i[15:0]}) | - ({32{mem_addr_index10}} & {mem_rs2_data_i[15:0], 16'h0}); + always @ (*) begin + sb_res = 32'h0; + case (1'b1) + mem_addr_index00: sb_res = {24'h0, mem_rs2_data_i[7:0]}; + mem_addr_index01: sb_res = {16'h0, mem_rs2_data_i[7:0], 8'h0}; + mem_addr_index10: sb_res = {8'h0, mem_rs2_data_i[7:0], 16'h0}; + mem_addr_index11: sb_res = {mem_rs2_data_i[7:0], 24'h0}; + endcase + end + + reg[31:0] sh_res; + + always @ (*) begin + sh_res = 32'h0; + case (1'b1) + mem_addr_index00: sh_res = {16'h0, mem_rs2_data_i[15:0]}; + mem_addr_index10: sh_res = {mem_rs2_data_i[15:0], 16'h0}; + endcase + end wire[31:0] sw_res = mem_rs2_data_i; - // load操作 - wire[31:0] lb_res = ({32{mem_addr_index00}} & {{24{mem_op_lb_i & mem_rdata_i[7]}}, mem_rdata_i[7:0]}) | - ({32{mem_addr_index01}} & {{24{mem_op_lb_i & mem_rdata_i[15]}}, mem_rdata_i[15:8]}) | - ({32{mem_addr_index10}} & {{24{mem_op_lb_i & mem_rdata_i[23]}}, mem_rdata_i[23:16]}) | - ({32{mem_addr_index11}} & {{24{mem_op_lb_i & mem_rdata_i[31]}}, mem_rdata_i[31:24]}); + reg[31:0] lb_res; - wire[31:0] lh_res = ({32{mem_addr_index00}} & {{24{mem_op_lh_i & mem_rdata_i[15]}}, mem_rdata_i[15:0]}) | - ({32{mem_addr_index10}} & {{24{mem_op_lh_i & mem_rdata_i[31]}}, mem_rdata_i[31:16]}); + always @ (*) begin + lb_res = 32'h0; + case (1'b1) + mem_addr_index00: lb_res = {{24{mem_op_lb_i & mem_rdata_i[7]}}, mem_rdata_i[7:0]}; + mem_addr_index01: lb_res = {{24{mem_op_lb_i & mem_rdata_i[15]}}, mem_rdata_i[15:8]}; + mem_addr_index10: lb_res = {{24{mem_op_lb_i & mem_rdata_i[23]}}, mem_rdata_i[23:16]}; + mem_addr_index11: lb_res = {{24{mem_op_lb_i & mem_rdata_i[31]}}, mem_rdata_i[31:24]}; + endcase + end + + reg[31:0] lh_res; + + always @ (*) begin + lh_res = 32'h0; + case (1'b1) + mem_addr_index00: lh_res = {{24{mem_op_lh_i & mem_rdata_i[15]}}, mem_rdata_i[15:0]}; + mem_addr_index10: lh_res = {{24{mem_op_lh_i & mem_rdata_i[31]}}, mem_rdata_i[31:16]}; + endcase + end wire[31:0] lw_res = mem_rdata_i; - // 写回内存或者寄存器的数据 - assign mem_wdata_o = ({32{mem_op_sb_i}} & sb_res) | - ({32{mem_op_sh_i}} & sh_res) | - ({32{mem_op_sw_i}} & sw_res) | - ({32{mem_op_lb_i | mem_op_lbu_i}} & lb_res) | - ({32{mem_op_lh_i | mem_op_lhu_i}} & lh_res) | - ({32{mem_op_lw_i}} & lw_res); + reg[31:0] mem_wdata; + always @ (*) begin + mem_wdata = 32'h0; + case (1'b1) + mem_op_sb_i: mem_wdata = sb_res; + mem_op_sh_i: mem_wdata = sh_res; + mem_op_sw_i: mem_wdata = sw_res; + mem_op_lb_i: mem_wdata = lb_res; + mem_op_lbu_i: mem_wdata = lb_res; + mem_op_lh_i: mem_wdata = lh_res; + mem_op_lhu_i: mem_wdata = lh_res; + mem_op_lw_i: mem_wdata = lw_res; + endcase + end + + assign mem_wdata_o = mem_wdata; wire mem_req_hsked = (mem_req_valid_o & mem_req_ready_i); wire mem_rsp_hsked = (mem_rsp_valid_i & mem_rsp_ready_o); diff --git a/rtl/core/exu_muldiv.v b/rtl/core/exu_muldiv.v index 4647a62..2433f4b 100644 --- a/rtl/core/exu_muldiv.v +++ b/rtl/core/exu_muldiv.v @@ -86,10 +86,17 @@ module exu_muldiv( wire[31:0] mulh_res = (op1_is_signed ^ op2_is_signed)? mul_res_tmp_complcode[63:32]: mul_res_tmp[63:32]; wire[31:0] mulhsu_res = (op1_is_signed)? mul_res_tmp_complcode[63:32]: mul_res_tmp[63:32]; - wire[31:0] mul_op_res = ({32{muldiv_op_mul_i}} & mul_res) | - ({32{muldiv_op_mulhu_i}} & mulhu_res) | - ({32{muldiv_op_mulh_i}} & mulh_res) | - ({32{muldiv_op_mulhsu_i}} & mulhsu_res); + reg[31:0] mul_op_res; + + always @ (*) begin + mul_op_res = 32'h0; + case (1'b1) + muldiv_op_mul_i: mul_op_res = mul_res; + muldiv_op_mulhu_i: mul_op_res = mulhu_res; + muldiv_op_mulh_i: mul_op_res = mulh_res; + muldiv_op_mulhsu_i: mul_op_res = mulhsu_res; + endcase + end // 运算结果 assign muldiv_reg_wdata_o = div_result | mul_op_res; diff --git a/rtl/core/ifu.v b/rtl/core/ifu.v index 0d0e8c0..8ab8193 100644 --- a/rtl/core/ifu.v +++ b/rtl/core/ifu.v @@ -46,6 +46,7 @@ module ifu( assign req_valid_o = (~rst_n)? 1'b0: (flush_i)? 1'b0: stall_i[`STALL_PC]? 1'b0: + jtag_halt_i? 1'b0: 1'b1; assign rsp_ready_o = (~rst_n)? 1'b0: 1'b1; @@ -53,7 +54,7 @@ module ifu( wire ifu_rsp_hsked = (rsp_valid_i & rsp_ready_o); // 在执行多周期指令或者请求不到总线时需要暂停 - wire stall = stall_i[`STALL_PC] | (~ifu_req_hsked) | jtag_halt_i; + wire stall = stall_i[`STALL_PC] | (~ifu_req_hsked); reg[31:0] pc; reg[31:0] pc_prev; diff --git a/rtl/core/rst_ctrl.v b/rtl/core/rst_ctrl.v new file mode 100644 index 0000000..bb8501d --- /dev/null +++ b/rtl/core/rst_ctrl.v @@ -0,0 +1,55 @@ + /* + Copyright 2020 Blue Liang, liangkangnan@163.com + + 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 rst_ctrl( + + input wire clk, + + input wire rst_ext_i, + input wire rst_jtag_i, + + output wire core_rst_n_o, + output wire jtag_rst_n_o + + ); + + wire ext_rst_r; + + gen_ticks_sync #( + .DP(2), + .DW(1) + ) ext_rst_sync( + .rst_n(rst_ext_i), + .clk(clk), + .din(1'b1), + .dout(ext_rst_r) + ); + + reg jtag_rst_r; + + always @ (posedge clk or posedge rst_jtag_i) begin + if (rst_jtag_i) begin + jtag_rst_r <= 1'b0; + end else begin + jtag_rst_r <= 1'b1; + end + end + + assign core_rst_n_o = ext_rst_r & jtag_rst_r; + assign jtag_rst_n_o = ext_rst_r; + +endmodule diff --git a/rtl/top/tinyriscv_soc_top.v b/rtl/top/tinyriscv_soc_top.v index 07de4e3..84ec790 100644 --- a/rtl/top/tinyriscv_soc_top.v +++ b/rtl/top/tinyriscv_soc_top.v @@ -20,10 +20,8 @@ module tinyriscv_soc_top( input wire clk, - input wire rst_n, + input wire rst_ext_i, - output reg over, // 测试是否完成信号 - output reg succ, // 测试是否成功信号 output wire halted_ind, // jtag是否已经halt住CPU信号 output wire uart_tx_pin, // UART发送引脚 @@ -147,6 +145,8 @@ module tinyriscv_soc_top( // tinyriscv wire[`INT_WIDTH-1:0] int_flag; + wire rst_n; + wire jtag_rst_n; // timer0 wire timer0_int; @@ -158,20 +158,19 @@ module tinyriscv_soc_top( assign int_flag = {{(`INT_WIDTH-1){1'b0}}, timer0_int}; + // 复位控制模块例化 + rst_ctrl u_rst_ctrl( + .clk(clk), + .rst_ext_i(rst_ext_i), + .rst_jtag_i(jtag_reset_req_o), + .core_rst_n_o(rst_n), + .jtag_rst_n_o(jtag_rst_n) + ); + // 低电平点亮LED // 低电平表示已经halt住CPU assign halted_ind = ~jtag_halt_req_o; - always @ (posedge clk or negedge rst_n) begin - if (!rst_n) begin - over <= 1'b1; - succ <= 1'b1; - end else begin - over <= ~u_tinyriscv_core.u_gpr_reg.regs[26]; // when = 1, run over - succ <= ~u_tinyriscv_core.u_gpr_reg.regs[27]; // when = 1, run succ, otherwise fail - end - end - // tinyriscv处理器核模块例化 tinyriscv_core u_tinyriscv_core( .clk(clk), @@ -302,7 +301,7 @@ module tinyriscv_soc_top( .DMI_OP_BITS(2) ) u_jtag_top( .clk(clk), - .jtag_rst_n(rst_n), + .jtag_rst_n(jtag_rst_n), .jtag_pin_TCK(jtag_TCK), .jtag_pin_TMS(jtag_TMS), .jtag_pin_TDI(jtag_TDI), diff --git a/sim/compile_rtl.py b/sim/compile_rtl.py index cb41ef9..2a3220f 100644 --- a/sim/compile_rtl.py +++ b/sim/compile_rtl.py @@ -44,6 +44,7 @@ def main(): iverilog_cmd.append(rtl_dir + r'/rtl/core/ifu_idu.v') iverilog_cmd.append(rtl_dir + r'/rtl/core/pipe_ctrl.v') iverilog_cmd.append(rtl_dir + r'/rtl/core/tinyriscv_core.v') + iverilog_cmd.append(rtl_dir + r'/rtl/core/rst_ctrl.v') # ../rtl/perips iverilog_cmd.append(rtl_dir + r'/rtl/perips/ram.v') iverilog_cmd.append(rtl_dir + r'/rtl/perips/rom.v') diff --git a/tb/compliance_test/tinyriscv_soc_tb.v b/tb/compliance_test/tinyriscv_soc_tb.v index f7dfcf5..92854ca 100644 --- a/tb/compliance_test/tinyriscv_soc_tb.v +++ b/tb/compliance_test/tinyriscv_soc_tb.v @@ -44,14 +44,16 @@ module tinyriscv_soc_tb; initial begin clk = 0; - rst_n = 1'b0; + rst_n = 1'b1; `ifdef TEST_JTAG TCK = 1; TMS = 1; TDI = 1; `endif $display("test running..."); - #40 + #100 + rst_n = 1'b0; + #100 rst_n = 1'b1; #200 /* @@ -520,7 +522,7 @@ module tinyriscv_soc_tb; tinyriscv_soc_top tinyriscv_soc_top_0( .clk(clk), - .rst_n(rst_n) + .rst_ext_i(rst_n) `ifdef TEST_JTAG , .jtag_TCK(TCK), diff --git a/tb/tinyriscv_soc_tb.v b/tb/tinyriscv_soc_tb.v index c0a6e0f..68dd84a 100644 --- a/tb/tinyriscv_soc_tb.v +++ b/tb/tinyriscv_soc_tb.v @@ -39,14 +39,16 @@ module tinyriscv_soc_tb; initial begin clk = 0; - rst_n = 1'b0; + rst_n = 1'b1; `ifdef TEST_JTAG TCK = 1; TMS = 1; TDI = 1; `endif $display("test running..."); - #40 + #100 + rst_n = 1'b0; + #100 rst_n = 1'b1; #200 @@ -506,7 +508,7 @@ module tinyriscv_soc_tb; tinyriscv_soc_top tinyriscv_soc_top_0( .clk(clk), - .rst_n(rst_n) + .rst_ext_i(rst_n) `ifdef TEST_JTAG , .jtag_TCK(TCK),