diff --git a/rtl/core/csr_reg.sv b/rtl/core/csr_reg.sv index 9abdb36..6a2793b 100644 --- a/rtl/core/csr_reg.sv +++ b/rtl/core/csr_reg.sv @@ -43,6 +43,8 @@ module csr_reg( ); + wire[31:0] misa = 32'h40001100; // 32bits, IM + reg[31:0] mtvec_d; wire[31:0] mtvec_q; reg mtvec_we; @@ -140,6 +142,9 @@ module csr_reg( `CSR_DCSR: begin exu_rdata = dcsr_q; end + `CSR_MISA: begin + exu_rdata = misa; + end default: begin exu_rdata = 32'h0; end @@ -349,4 +354,11 @@ module csr_reg( .rdata_o(dcsr_q) ); + wire[31:0] mtvec = mtvec_q; + wire[31:0] mstatus = mstatus_q; + wire[31:0] mepc = mepc_q; + wire[31:0] mie = mie_q; + wire[31:0] dpc = dpc_q; + wire[31:0] dcsr = dcsr_q; + endmodule diff --git a/rtl/core/defines.sv b/rtl/core/defines.sv index 0864ded..49b7c6a 100644 --- a/rtl/core/defines.sv +++ b/rtl/core/defines.sv @@ -144,3 +144,4 @@ `define CSR_DPC 12'h7b1 `define CSR_DSCRATCH0 12'h7b2 `define CSR_DSCRATCH1 12'h7b3 +`define CSR_MISA 12'h301 diff --git a/rtl/core/exception.sv b/rtl/core/exception.sv index 3dbbf18..0f85423 100644 --- a/rtl/core/exception.sv +++ b/rtl/core/exception.sv @@ -160,7 +160,7 @@ module exception ( exception_req = 1'b1; exception_cause = `CAUSE_EXCEP_ECALL_M; exception_offset = ECALL_OFFSET; - end else if (inst_ebreak_i & (!dcsr_i[15])) begin + end else if (inst_ebreak_i & (!dcsr_i[15]) & (~debug_mode_q)) begin exception_req = 1'b1; exception_cause = `CAUSE_EXCEP_EBREAK_M; exception_offset = EBREAK_OFFSET; @@ -179,7 +179,9 @@ module exception ( assign int_or_exception_cause = exception_req ? exception_cause : interrupt_cause; assign int_or_exception_offset = exception_req ? exception_offset : interrupt_offset; - wire debug_mode_req = ((~debug_mode_q) & debug_req_i & inst_valid_i) | (inst_ebreak_i & dcsr_i[15]); + wire debug_mode_req = ((~debug_mode_q) & debug_req_i & inst_valid_i) | + (inst_ebreak_i & dcsr_i[15]) | + (inst_ebreak_i & debug_mode_q); assign stall_flag_o = ((state_q != S_IDLE) & (state_q != S_ASSERT)) | (interrupt_req & global_int_en) | exception_req | diff --git a/rtl/core/tracer.sv b/rtl/core/tracer.sv index 12d9ad9..2a51e6c 100644 --- a/rtl/core/tracer.sv +++ b/rtl/core/tracer.sv @@ -331,7 +331,8 @@ module tracer( 12'd1955: return "tdata3"; 12'd1968: return "dcsr"; 12'd1969: return "dpc"; - 12'd1970: return "dscratch"; + 12'd1970: return "dscratch0"; + 12'd1971: return "dscratch1"; 12'd512: return "hstatus"; 12'd514: return "hedeleg"; 12'd515: return "hideleg"; diff --git a/rtl/debug/debug_rom.sv b/rtl/debug/debug_rom.sv index 229b7a5..9868212 100644 --- a/rtl/debug/debug_rom.sv +++ b/rtl/debug/debug_rom.sv @@ -1,71 +1,88 @@ -/* Copyright 2018 ETH Zurich and University of Bologna. - * Copyright and related rights are licensed under the Solderpad Hardware - * License, Version 0.51 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law - * or agreed to in writing, software, hardware and materials distributed under - * this 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. - * - * File: $filename.v - * - * Description: Auto-generated bootrom + /* + Copyright 2021 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. */ -// Auto-generated code module debug_rom ( - input wire clk_i, - input wire req_i, - input wire [63:0] addr_i, - output wire [63:0] rdata_o -); + input wire clk_i, + input wire req_i, + input wire [31:0] addr_i, + output wire [31:0] rdata_o + ); - localparam RomSize = 19; + localparam RomSize = 38; - wire [RomSize-1:0][63:0] mem; + wire [RomSize-1:0][31:0] mem; - assign mem = { - 64'h00000000_7b200073, - 64'h7b202473_7b302573, - 64'h10852423_f1402473, - 64'ha85ff06f_7b202473, - 64'h7b302573_10052223, - 64'h00100073_7b202473, - 64'h7b302573_10052623, - 64'h00c51513_00c55513, - 64'h00000517_fd5ff06f, - 64'hfa041ce3_00247413, - 64'h40044403_00a40433, - 64'hf1402473_02041c63, - 64'h00147413_40044403, - 64'h00a40433_10852023, - 64'hf1402473_00c51513, - 64'h00c55513_00000517, - 64'h7b351073_7b241073, - 64'h0ff0000f_04c0006f, - 64'h07c0006f_00c0006f - }; + assign mem = { + 32'h00000000, + 32'h7b200073, + 32'h7b202473, + 32'h7b302573, + 32'h10852423, + 32'hf1402473, + 32'ha85ff06f, + 32'h7b202473, + 32'h7b302573, + 32'h10052223, + 32'h00100073, + 32'h7b202473, + 32'h7b302573, + 32'h10052623, + 32'h00c51513, + 32'h00c55513, + 32'h00000517, + 32'hfd5ff06f, + 32'hfa041ce3, + 32'h00247413, + 32'h40044403, + 32'h00a40433, + 32'hf1402473, + 32'h02041c63, + 32'h00147413, + 32'h40044403, + 32'h00a40433, + 32'h10852023, + 32'hf1402473, + 32'h00c51513, + 32'h00c55513, + 32'h00000517, + 32'h7b351073, + 32'h7b241073, + 32'h0ff0000f, + 32'h04c0006f, + 32'h07c0006f, + 32'h00c0006f + }; - reg [4:0] addr_q; + reg [5:0] addr_q; - always @ (posedge clk_i) begin - if (req_i) begin - addr_q <= addr_i[7:3]; + always @ (posedge clk_i) begin + if (req_i) begin + addr_q <= addr_i[7:2]; + end end - end - reg[63:0] rdata; + reg[31:0] rdata; - // this prevents spurious Xes from propagating into - // the speculative fetch stage of the core - always @ (*) begin - rdata = 64'h0; - if (addr_q < 5'd19) begin - rdata = mem[addr_q]; + always @ (*) begin + rdata = 32'h0; + if (addr_q < 6'd38) begin + rdata = mem[addr_q]; + end end - end - assign rdata_o = rdata; + assign rdata_o = rdata; endmodule diff --git a/rtl/debug/jtag_mem.sv b/rtl/debug/jtag_mem.sv index de211e8..e473461 100644 --- a/rtl/debug/jtag_mem.sv +++ b/rtl/debug/jtag_mem.sv @@ -176,11 +176,11 @@ module jtag_mem( reg resuming_d, resuming_q; reg resume, go, going; reg fwd_rom_q; - reg word_enable32_q; reg data_valid; reg cmdbusy; + reg halted_aligned; wire fwd_rom_d; - wire[63:0] rom_rdata; + wire[31:0] rom_rdata; reg[31:0] data_bits; reg[9:0][31:0] abstract_cmd; reg unsupported_command; @@ -197,10 +197,9 @@ module jtag_mem( wire[2:0] cmd_aarsize = cmd_i[22:20]; wire cmd_aarpostincrement = cmd_i[19]; - // word mux for 32bit and 64bit buses - wire [63:0] word_mux; + wire[31:0] word_mux; assign word_mux = fwd_rom_q ? rom_rdata : rdata_q; - assign rdata_o = (word_enable32_q) ? word_mux[32 +: 32] : word_mux[0 +: 32]; + assign rdata_o = word_mux; assign halted_o = halted_q; assign resumeack_o = resuming_q; @@ -253,7 +252,7 @@ module jtag_mem( S_CMD_EXECUTING: begin cmdbusy = 1'b1; go = 1'b0; - if (halted_q) begin + if (halted_aligned) begin state_d = S_IDLE; end end @@ -278,6 +277,7 @@ module jtag_mem( going = 1'b0; exception = 1'b0; + halted_aligned = 1'b0; data_valid = 1'b0; data_bits = data_i; @@ -291,6 +291,7 @@ module jtag_mem( case (addr_i[DbgAddressBits-1:0]) HaltedAddr: begin halted_d = 1'b1; + halted_aligned = 1'b1; end GoingAddr: begin @@ -349,15 +350,15 @@ module jtag_mem( Progbuf0Addr, Progbuf1Addr, Progbuf2Addr, Progbuf3Addr, Progbuf4Addr, Progbuf5Addr, Progbuf6Addr, Progbuf7Addr, Progbuf8Addr, Progbuf9Addr: begin - rdata_d = progbuf_i[addr_i[DbgAddressBits-1:3] - - progbuf_baseaddr[DbgAddressBits-1:3]]; + rdata_d = progbuf_i[addr_i[DbgAddressBits-1:2] - + progbuf_baseaddr[DbgAddressBits-1:2]]; end AbstractCmd0Addr, AbstractCmd1Addr, AbstractCmd2Addr, AbstractCmd3Addr, AbstractCmd4Addr, AbstractCmd5Addr, AbstractCmd6Addr, AbstractCmd7Addr, AbstractCmd8Addr, AbstractCmd9Addr: begin - rdata_d = abstract_cmd[addr_i[DbgAddressBits-1:3] - - abstractcmd_baseaddr[DbgAddressBits-1:3]]; + rdata_d = abstract_cmd[addr_i[DbgAddressBits-1:2] - + abstractcmd_baseaddr[DbgAddressBits-1:2]]; end default:; @@ -464,8 +465,8 @@ module jtag_mem( endcase end - wire[63:0] rom_addr; - assign rom_addr = {32'h0, addr_i}; + wire[31:0] rom_addr; + assign rom_addr = addr_i; assign fwd_rom_d = addr_i[DbgAddressBits-1:0] >= `HaltAddress; @@ -480,13 +481,11 @@ module jtag_mem( if (!rst_n) begin rdata_q <= 32'h0; fwd_rom_q <= 1'b0; - word_enable32_q <= 1'b0; halted_q <= 1'b0; resuming_q <= 1'b0; end else begin rdata_q <= rdata_d; fwd_rom_q <= fwd_rom_d; - word_enable32_q <= addr_i[2]; halted_q <= halted_d; resuming_q <= resuming_d; end diff --git a/sim/tb_top_verilator.sv b/sim/tb_top_verilator.sv index 0fdd2fc..64dfe89 100644 --- a/sim/tb_top_verilator.sv +++ b/sim/tb_top_verilator.sv @@ -15,10 +15,12 @@ module tb_top_verilator #( ) ( - input clk_i, - input rst_ni + input wire clk_i, + input wire rst_ni ); + wire halted; + wire[31:0] x26 = u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.regs[26]; wire[31:0] x27 = u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.regs[27]; @@ -26,9 +28,8 @@ module tb_top_verilator #( automatic logic [1023:0] firmware; if($value$plusargs("firmware=%s", firmware)) begin - //if($test$plusargs("verbose")) - $display("[TESTBENCH] %t: loading firmware %0s ...", - $time, firmware); + $display("[TESTBENCH] %t: loading firmware %0s ...", + $time, firmware); $readmemh (firmware, u_tinyriscv_soc_top.u_rom.u_gen_ram.ram); end else begin $display("No firmware specified"); @@ -72,7 +73,65 @@ module tb_top_verilator #( tinyriscv_soc_top u_tinyriscv_soc_top( .clk(clk_i), - .rst_ext_ni(rst_ni) + .rst_ext_ni(rst_ni), + .halted_ind_pin(halted) ); + wire display_regs = 1'b0; + + wire write_gpr_reg = u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.we_i; + wire[4:0] write_gpr_addr = u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.waddr_i; + + wire write_csr_reg = u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.exu_we_i; + wire[31:0] write_csr_addr = u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.exu_waddr_i; + + always @ (posedge clk_i) begin + if (halted && write_gpr_reg && display_regs && (write_gpr_addr == 5'd31)) begin + $display("\n"); + $display("ra = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.ra); + $display("sp = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.sp); + $display("gp = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.gp); + $display("tp = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.tp); + $display("t0 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.t0); + $display("t1 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.t1); + $display("t2 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.t2); + $display("s0 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s0); + $display("fp = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.fp); + $display("s1 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s1); + $display("a0 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.a0); + $display("a1 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.a1); + $display("a2 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.a2); + $display("a3 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.a3); + $display("a4 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.a4); + $display("a5 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.a5); + $display("a6 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.a6); + $display("a7 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.a7); + $display("s2 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s2); + $display("s3 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s3); + $display("s4 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s4); + $display("s5 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s5); + $display("s6 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s6); + $display("s7 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s7); + $display("s8 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s8); + $display("s9 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s9); + $display("s10 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s10); + $display("s11 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.s11); + $display("t3 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.t3); + $display("t4 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.t4); + $display("t5 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.t5); + $display("t6 = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_gpr_reg.t6); + end else if (halted && write_csr_reg && display_regs && (write_csr_addr[11:0] == 12'hc00)) begin + $display("\n"); + $display("misa = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.misa); + $display("cycle = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.cycle[31:0]); + $display("cycleh = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.cycle[63:32]); + $display("mtvec = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.mtvec); + $display("mstatus = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.mstatus); + $display("mepc = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.mepc); + $display("mie = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.mie); + $display("dpc = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.dpc); + $display("dcsr = 0x%x", u_tinyriscv_soc_top.u_tinyriscv_core.u_csr_reg.dcsr); + end + end + endmodule // tb_top_verilator