diff --git a/Makefile b/Makefile index 0989b8051..ba9928ceb 100755 --- a/Makefile +++ b/Makefile @@ -193,6 +193,7 @@ verilate: -Werror-IMPLICIT \ -Wno-fatal \ -Wno-PINCONNECTEMPTY \ + -Wno-ASSIGNDLY \ -Wno-DECLFILENAME \ -Wno-UNOPTFLAT \ -Wno-UNUSED \ diff --git a/bootrom/bootrom.sv b/bootrom/bootrom.sv index f05c4032d..89c0faa07 100644 --- a/bootrom/bootrom.sv +++ b/bootrom/bootrom.sv @@ -44,7 +44,7 @@ module bootrom ( always_ff @(posedge clk_i) begin if (req_i) begin - addr_q = addr_i[$clog2(RomSize)-1+3:3]; + addr_q <= addr_i[$clog2(RomSize)-1+3:3]; end end diff --git a/bootrom/gen_rom.py b/bootrom/gen_rom.py index 886b97b41..5314c3f1e 100755 --- a/bootrom/gen_rom.py +++ b/bootrom/gen_rom.py @@ -55,7 +55,7 @@ module $filename ( always_ff @(posedge clk_i) begin if (req_i) begin - addr_q = addr_i[$$clog2(RomSize)-1+3:3]; + addr_q <= addr_i[$$clog2(RomSize)-1+3:3]; end end diff --git a/include/ariane_pkg.sv b/include/ariane_pkg.sv index 006f86f53..159a13b28 100755 --- a/include/ariane_pkg.sv +++ b/include/ariane_pkg.sv @@ -47,9 +47,16 @@ package ariane_pkg; // 32 registers + 1 bit for re-naming = 6 localparam REG_ADDR_SIZE = 6; + // static debug hartinfo - // for the moment nothing of this is implemented - parameter dm::hartinfo_t DebugHartInfo = '{zero1: '0, nscratch: 1, zero0: '0, dataaccess: 1'b1, datasize: '0, dataaddr: '0}; + parameter dm::hartinfo_t DebugHartInfo = '{ + zero1: '0, + nscratch: 1, // DTM currently needs at least one scratch register + zero0: '0, + dataaccess: 1'b1, // data registers are memory mapped in the debugger + datasize: dm::DataCount, + dataaddr: dm::DataAddr + }; // --------------- // Fetch Stage // --------------- @@ -300,4 +307,5 @@ package ariane_pkg; function automatic logic [63:0] sb_imm (logic [31:0] instruction_i); return { {51 {instruction_i[31]}}, instruction_i[31], instruction_i[7], instruction_i[30:25], instruction_i[11:8], 1'b0 }; endfunction + endpackage diff --git a/include/riscv_pkg.sv b/include/riscv_pkg.sv index 3b763e49b..d4ea5e110 100644 --- a/include/riscv_pkg.sv +++ b/include/riscv_pkg.sv @@ -129,24 +129,24 @@ package riscv; // -------------------- // Opcodes // -------------------- - localparam OpcodeSystem = 7'h73; - localparam OpcodeFence = 7'h0f; - localparam OpcodeOp = 7'h33; - localparam OpcodeOp32 = 7'h3B; - localparam OpcodeOpimm = 7'h13; - localparam OpcodeOpimm32 = 7'h1B; - localparam OpcodeStore = 7'h23; - localparam OpcodeLoad = 7'h03; - localparam OpcodeBranch = 7'h63; - localparam OpcodeJalr = 7'h67; - localparam OpcodeJal = 7'h6f; - localparam OpcodeAuipc = 7'h17; - localparam OpcodeLui = 7'h37; - localparam OpcodeAmo = 7'h2F; + parameter OpcodeSystem = 7'h73; + parameter OpcodeFence = 7'h0f; + parameter OpcodeOp = 7'h33; + parameter OpcodeOp32 = 7'h3B; + parameter OpcodeOpimm = 7'h13; + parameter OpcodeOpimm32 = 7'h1B; + parameter OpcodeStore = 7'h23; + parameter OpcodeLoad = 7'h03; + parameter OpcodeBranch = 7'h63; + parameter OpcodeJalr = 7'h67; + parameter OpcodeJal = 7'h6f; + parameter OpcodeAuipc = 7'h17; + parameter OpcodeLui = 7'h37; + parameter OpcodeAmo = 7'h2F; - localparam OpcodeCJ = 3'b101; - localparam OpcodeCBeqz = 3'b110; - localparam OpcodeCBnez = 3'b111; + parameter OpcodeCJ = 3'b101; + parameter OpcodeCBeqz = 3'b110; + parameter OpcodeCBnez = 3'b111; // ----- // CSRs @@ -238,4 +238,28 @@ package riscv; csr_addr_t csr_decode; } csr_t; + // Instruction Generation *incomplete* + function automatic logic [31:0] jal (logic[4:0] rd, logic [20:0] imm); + // OpCode Jal + return {imm[20], imm[10:1], imm[11], imm[19:12], rd, 7'h6f}; + endfunction + + function automatic logic [31:0] load (logic [2:0] size, logic[4:0] rd, logic[4:0] rs1, logic [11:0] imm); + // OpCode Load + return {imm[11:0], rs1, size, rd, 7'h03}; + endfunction + + function automatic logic [31:0] store (logic [2:0] size, logic[4:0] rs1, logic[4:0] rs2, logic [11:0] imm); + // OpCode Store + return {imm[11:5], rs2, rs1, size, imm[4:0], 7'h23}; + endfunction + + function automatic logic [31:0] ebreak (); + return 32'h00100073; + endfunction + + function automatic logic [31:0] nop (); + return 32'h00000013; + endfunction + endpackage diff --git a/src/csr_regfile.sv b/src/csr_regfile.sv index 3f2547dec..72497a1b4 100644 --- a/src/csr_regfile.sv +++ b/src/csr_regfile.sv @@ -728,6 +728,11 @@ module csr_regfile #( trap_vector_base_o = {stvec_q[63:2], 2'b0}; end + // if we are in debug mode jump to a specific address + if (debug_mode_q) begin + trap_vector_base_o = dm::ExceptionAddress; + end + // check if we are in vectored mode, if yes then do BASE + 4 * cause // we are imposing an additional alignment-constraint of 64 * 4 bytes since // we want to spare the costly addition diff --git a/src/debug/debug_rom/debug_rom.sv b/src/debug/debug_rom/debug_rom.sv index 9653ac013..e295075e7 100644 --- a/src/debug/debug_rom/debug_rom.sv +++ b/src/debug/debug_rom/debug_rom.sv @@ -41,7 +41,7 @@ module debug_rom ( always_ff @(posedge clk_i) begin if (req_i) begin - addr_q = addr_i[$clog2(RomSize)-1+3:3]; + addr_q <= addr_i[$clog2(RomSize)-1+3:3]; end end diff --git a/src/debug/dm_csrs.sv b/src/debug/dm_csrs.sv index f75d6c10e..8f6741a12 100644 --- a/src/debug/dm_csrs.sv +++ b/src/debug/dm_csrs.sv @@ -37,7 +37,6 @@ module dm_csrs #( // hart status input dm::hartinfo_t [NrHarts-1:0] hartinfo_i, // static hartinfo input logic [NrHarts-1:0] halted_i, // hart is halted - input logic [NrHarts-1:0] running_i, // hart is running input logic [NrHarts-1:0] unavailable_i, // e.g.: powered down input logic [NrHarts-1:0] havereset_i, // hart has reset input logic [NrHarts-1:0] resumeack_i, // hart acknowledged resume request @@ -45,13 +44,18 @@ module dm_csrs #( output logic [NrHarts-1:0] haltreq_o, // request to halt a hart output logic [NrHarts-1:0] resumereq_o, // request hart to resume output logic [NrHarts-1:0] ackhavereset_o, // DM acknowledges reset - output logic command_write_o, // debugger is writing to the command field - output dm::command_t command_o, // abstract command - input logic [NrHarts-1:0] set_cmderror_i, // an error occured - input dm::cmderr_t [NrHarts-1:0] cmderror_i, // this error occured - input logic [NrHarts-1:0] cmdbusy_i, // cmd is currently busy executing + + output logic cmd_valid_o, // debugger is writing to the command field + output dm::command_t cmd_o, // abstract command + input logic [NrHarts-1:0] cmderror_valid_i, // an error occured + input dm::cmderr_t [NrHarts-1:0] cmderror_i, // this error occured + input logic [NrHarts-1:0] cmdbusy_i, // cmd is currently busy executing + output logic [dm::ProgBufSize-1:0][31:0] progbuf_o, // to system bus - output logic [dm::DataCount-1:0][31:0] data_o // optional data register (to system bus) + output logic [dm::DataCount-1:0][31:0] data_o, + + output logic [dm::DataCount-1:0][31:0] data_i, + output logic data_valid_i ); // the amount of bits we need to represent all harts localparam HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts); @@ -122,8 +126,8 @@ module dm_csrs #( dmstatus.allhalted = halted_i[hartsel[HartSelLen-1:0]]; dmstatus.anyhalted = halted_i[hartsel[HartSelLen-1:0]]; - dmstatus.allrunning = running_i[hartsel[HartSelLen-1:0]]; - dmstatus.anyrunning = running_i[hartsel[HartSelLen-1:0]]; + dmstatus.allrunning = ~halted_i[hartsel[HartSelLen-1:0]]; + dmstatus.anyrunning = ~halted_i[hartsel[HartSelLen-1:0]]; // abstractcs abstractcs = '0; @@ -140,7 +144,7 @@ module dm_csrs #( data_d = data_q; resp_queue_data = 32'0; - command_write_o = 1'b0; + cmd_valid_o = 1'b0; ackhavereset_o = 'b0; // read @@ -154,7 +158,8 @@ module dm_csrs #( dm::DMStatus: resp_queue_data = dmstatus; dm::Hartinfo: resp_queue_data = hartinfo_i[selected_hart]; dm::AbstractCS: resp_queue_data = abstractcs; - dm::Command: resp_queue_data = command_q; + // command is read-only + dm::Command: resp_queue_data = '0; [(dm::ProgBuf0):(dm::ProgBuf0 + dm::ProgBufSize)]: begin resp_queue_data = progbuf_q[dmi_req_bits_addr_i[4:0]]; end @@ -184,14 +189,31 @@ module dm_csrs #( dm::DMStatus:; // write are ignored to R/O register dm::Hartinfo:; // hartinfo is R/O // only command error is write-able - dm::AbstractCS: begin + dm::AbstractCS: begin // W1C + // Gets set if an abstract command fails. The bits in this + // field remain set until they are cleared by writing 1 to + // them. No abstract command is started until the value is + // reset to 0. automatic dm::abstractcs_t abstractcs; abstractcs = dm::abstractcs_t'(dmi_req_bits_data_i); - cmderr_d = abstractcs.cmderr; + // reads during abstract command execution are not allowed + if (!cmdbusy_i) begin + cmderr_d = ~abstractcs.cmderr & cmderr_q; + end else if (cmderr_q == dm::CmdErrNone) begin + cmderr_d = dm::CmdErrBusy; + end + end dm::Command: begin - command_write_o = 1'b1; - command_d = dmi_req_bits_data_i; + // writes are ignored if a command is already busy + if (!cmdbusy_i) begin + cmd_valid_o = 1'b1; + command_d = dmi_req_bits_data_i; + // if there was an attempted to write during a busy execution + // and the cmderror field is zero set the busy error + end else if (cmderr_q == dm::CmdErrNone) begin + cmderr_d = dm::CmdErrBusy; + end end [(dm::ProgBuf0):(dm::ProgBuf0 + dm::ProgBufSize)]: begin // attempts to write them while busy is set does not change their value @@ -203,9 +225,14 @@ module dm_csrs #( endcase end // hart threw a command error and has precedence over bus writes - if (set_cmderror_i[selected_hart]) begin + if (cmderror_valid_i[selected_hart]) begin cmderr_d = cmderror_i[selected_hart]; end + + // update data registers + if (data_valid_i) + data_d = data_i; + // dmcontrol // TODO(zarubaf) we currently do not implement the hartarry mask dmcontrol_d.hasel = 1'b0; @@ -232,7 +259,7 @@ module dm_csrs #( assign dmactive_o = dmcontrol_q.dmactive; // if the PoR is set we want to re-set the other system as well assign ndmreset_o = dmcontrol_q.ndmreset | (~rst_ni); - assign command_o = command_q; + assign cmd_o = command_q; assign progbuf_o = progbuf_q; assign data_o = data_q; // response FIFO diff --git a/src/debug/dm_ctrl.sv b/src/debug/dm_ctrl.sv index 58ff9200a..69b35e1c5 100644 --- a/src/debug/dm_ctrl.sv +++ b/src/debug/dm_ctrl.sv @@ -39,6 +39,7 @@ module dm_ctrl ( output logic cmdbusy_o, // from hart communication module input logic halted_i // hart is halted + // input logic command_finished_i ); logic havereset_d, havereset_q; @@ -47,7 +48,7 @@ module dm_ctrl ( assign havereset_o = havereset_q; typedef enum logic [1:0] { - kRunning, kHaltReq, kHalted + kRunning, kHaltReq, kHalted, kCommandExec } state_t; state_t state_d, state_q; @@ -55,7 +56,6 @@ module dm_ctrl ( always_comb begin state_d = state_q; - halted_o = 1'b0; running_o = 1'b0; unavailable_o = 1'b0; @@ -78,8 +78,15 @@ module dm_ctrl ( end kHalted: begin - + halted_o = 1'b1; + // if (command_write_i) state_d = kHalted; end + + kCommandExec: begin + // halted_o = 1'b1; + // if (command_finished_i) state_d = kHalted; + end + endcase end diff --git a/src/debug/dm_mem.sv b/src/debug/dm_mem.sv index eeadcef73..c55b9ec28 100644 --- a/src/debug/dm_mem.sv +++ b/src/debug/dm_mem.sv @@ -19,72 +19,243 @@ module dm_mem #( parameter int NrHarts = -1 )( - input logic clk_i, // Clock - input logic dmactive_i, // debug module reset + input logic clk_i, // Clock + input logic dmactive_i, // debug module reset - output logic [NrHarts-1:0] halted_o, // hart acknowledge halt - output logic [NrHarts-1:0] going_o, // hart is running - output logic [NrHarts-1:0] resuming_o, // hart is resuming - output logic [NrHarts-1:0] exception_o, // hart ran into an exception + output logic debug_req_o, + // from Ctrl and Status register + input logic [NrHarts-1:0] haltreq_i, + input logic [NrHarts-1:0] resumereq_i, + + // state bits + output logic [NrHarts-1:0] halted_o, // hart acknowledge halt + output logic [NrHarts-1:0] resuming_o, // hart is resuming + + input logic [dm::ProgBufSize-1:0][31:0] progbuf_i, // program buffer to expose + + output logic [dm::DataCount-1:0][31:0] data_i, // data in + output logic [dm::DataCount-1:0][31:0] data_o, // data out + output logic data_valid_o, // data out is valid + // abstract command interface + input logic cmd_valid_i, + input dm::command_t cmd_i, + output logic cmderror_valid_o, + output dm::cmderr_t cmderror_o, + output logic cmdbusy_o, + // data interface - input logic [dm::ProgBufSize-1:0][31:0] progbuf_i, // program buffer to expose - input logic [dm::DataCount-1:0][31:0] data_i, // data in // SRAM interface - input logic req_i, - input logic we_i, - input logic [63:0] addr_i, - input logic [63:0] wdata_i, - input logic [7:0] be_i, - output logic [63:0] rdata_o + input logic req_i, + input logic we_i, + input logic [63:0] addr_i, + input logic [63:0] wdata_i, + input logic [7:0] be_i, + output logic [63:0] rdata_o ); - localparam HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts); + + localparam DbgAddressBits = 12; + localparam HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts); + localparam DataAddr = dm::DataAddr; + localparam ProgBufBase = dm::DataAddr - 4*dm::DataCount; + localparam AbstractCmdBase = ProgBufBase - 4*dm::ProgBufSize; + + localparam logic [DbgAddressBits-1:0] Halted = 'h100; + localparam logic [DbgAddressBits-1:0] Going = 'h104; + localparam logic [DbgAddressBits-1:0] Resuming = 'h108; + localparam logic [DbgAddressBits-1:0] Exception = 'h10C; + localparam logic [DbgAddressBits-1:0] WhereTo = 'h300; + localparam logic [DbgAddressBits-1:0] Flags = 'h400; + localparam logic [7:0] FlagGo = 7'b0; + localparam logic [7:0] FlagResume = 7'b1; + + logic [NrHarts-1:0] halted_d, halted_q; + logic [NrHarts-1:0] resuming_d, resuming_q; + logic cmdbusy_d, cmdbusy_q; + + logic [HartSelLen-1:0] hart_sel; + logic going, exception, halted; + logic unsupported_command; logic [63:0] rom_rdata; + logic [63:0] rdata_d, rdata_q; // distinguish whether we need to forward data from the ROM or the FSM // latch the address for this logic fwd_rom_d, fwd_rom_q; + assign hart_sel = wdata_i[HartSelLen-1:0]; + assign debug_req_o = haltreq_i; + assign halted_o = halted_q; + assign resuming_o = resuming_q; + assign cmdbusy_o = cmdbusy_q; + + // abstract command ctrl + always_comb begin + cmderror_valid_o = 1'b0; + cmderror_o = '0; + cmdbusy_d = cmdbusy_q; + + if (exception) begin + cmderror_valid_o = 1'b1; + cmderror_o = dm::CmdErrorException; + end + + // we've got a new command + if (cmd_valid_i && halted_q) begin + cmdbusy_d = 1'b1; + // release the go flag + end else if (cmd_valid_i) begin + // hart must be halted for all requests + cmderror_valid_o = 1'b1; + cmderror_o = dm::CmdErrorHaltResume; + end + + // we've halted again ~> clear the busy flag + if (halted) begin + cmdbusy_d = 1'b0; + end + + if (unsupported_command) begin + cmderror_valid_o = 1'b1; + cmderror_o = dm::CmdErrNotSupported; + end + end + + // read/write logic + always_comb begin + halted_d = halted_q; + resuming_d = resuming_q; + rdata_o = fwd_rom_q ? rom_rdata : rdata_q; + rdata_d = rdata_q; + data_o = data_i; + // write data in csr register + data_valid_o = 1'b0; + exception = 1'b0; + halted = 1'b0; + unsupported_command = 1'b0; + // we've got a new request + if (req_i) begin + // this is a write + if (we_i) begin + unique case (addr_i[DbgAddressBits-1:0]) inside + Halted: begin + halted = 1'b1; + halted_d[hart_sel] = 1'b1; + resuming_d[hart_sel] = 1'b0; + end + Going:; + Resuming: begin + halted_d[hart_sel] = 1'b0; + resuming_d[hart_sel] = 1'b1; + end + // an exception occurred during execution + Exception: exception = 1'b1; + // core can write data registers + // TODO(zarubaf) Remove hard-coded values + (dm::DataAddr || dm::DataAddr+4): begin + // data_valid_o = 1'b1; + for (int i = 0; i < $bits(be_i); i++) begin + if (be_i[i]) begin + // data_o = wdata_i[i*8+:8]; + end + end + end + + // harts are polling for flags here + [Flags:AbstractCmdBase] begin + + end + endcase + + // this is a read + end else begin + unique case (addr_i[DbgAddressBits-1:0]) inside + // variable ROM content + WhereTo: begin + // variable jump to abstract cmd, program_buffer or resume + if (resumereq_i) begin + rdata_d = {32'b0, riscv::jal(0, dm::ResumeAddress)}; + end + + // there is a command active so jump there + if (cmdbusy_q) begin + rdata_d = {32'b0, riscv::jal(0, AbstractCmdBase)}; + end + end + + // TODO(zarubaf) change hard-coded values + // TODO(zarubaf) submit verilator bug report + // %Error: Internal Error: src/debug/dm_mem.sv:129: ../V3Hashed.cpp:73: sameHash function undefined (returns 0) for node under CFunc. + (dm::DataAddr || dm::DataAddr+4): begin + rdata_d = {data_i[1], data_i[0]}; + end + + [ProgBufBase:(dm::DataAddr-4)]: begin + // TODO(zarubaf) change hard-coded values + rdata_d = {progbuf_i[1], progbuf_i[0]}; + end + // two slots for abstract command + [AbstractCmdBase:AbstractCmdBase+4]: begin + rdata_d = '0; + // this depends on the command being executed + unique case (cmd_i.cmdtype) + // -------------------- + // Access Register + // -------------------- + dm::AccessRegister: begin + automatic dm::ac_ar_cmd_t ac_ar; + ac_ar = dm::ac_ar_cmd_t'(cmd_i.control); + + if (ac_ar.transfer && ac_ar.write) begin + rdata_d[0] = riscv::store(ac_ar.aarsize, ac_ar.regno[4:0], 0, dm::DataAddr); + end else if (ac_ar.transfer) begin + rdata_d[0] = riscv::load(ac_ar.aarsize, ac_ar.regno[4:0], 0, dm::DataAddr); + end + // check whether we need to execute the program buffer + if (ac_ar.postexec) begin + // issue a nop, we will automatically run into the program buffer + rdata_d[1] = riscv::nop(); + end else begin + // transfer control back to idle loop + rdata_d[1] = riscv::ebreak(); + end + end + // not supported at the moment + // dm::QuickAccess:; + // dm::AccessMemory:; + default: begin + unsupported_command = 1'b1; + end + endcase + end + endcase + end + end + end + debug_rom i_debug_rom ( .clk_i, .req_i, .addr_i, .rdata_o (rom_rdata) ); - logic [HartSelLen-1:0] hart_sel; - assign hart_sel = wdata_i[HartSelLen-1:0]; - // read/write logic - always_comb begin - halted_o = '0; - going_o = '0; - resuming_o = '0; - exception_o = '0; - rdata_o = fwd_rom_q ? rom_rdata : '0; - // we've got a new request - if (req_i) begin - // this is a write - if (we_i) begin - case (addr_i[dm::DbgAddressBits-1:0]) - dm::Halted: halted_o[hart_sel] = 1'b1; - dm::Going: going_o[hart_sel] = 1'b1; - dm::Resuming: resuming_o[hart_sel] = 1'b1; - dm::Exception: exception_o[hart_sel] = 1'b1; - endcase - // this is a read - end else begin - - end - end - end // ROM starts at the HaltAddress of the core e.g.: it immediately jumps to // the ROM base address - assign fwd_rom_d = (addr_i[dm::DbgAddressBits-1:0] >= dm::HaltAddress) ? 1'b1 : 1'b0; + assign fwd_rom_d = (addr_i[DbgAddressBits-1:0] >= dm::HaltAddress) ? 1'b1 : 1'b0; always_ff @(posedge clk_i) begin if (~dmactive_i) begin - fwd_rom_q <= 1'b0; + fwd_rom_q <= 1'b0; + rdata_q <= '0; + halted_q <= 1'b0; + resuming_q <= 1'b0; + cmdbusy_q <= 1'b0; end else begin - fwd_rom_q <= fwd_rom_d; + fwd_rom_q <= fwd_rom_d; + rdata_q <= rdata_d; + halted_q <= halted_d; + resuming_q <= resuming_d; + cmdbusy_q <= cmdbusy_d; end end diff --git a/src/debug/dm_pkg.sv b/src/debug/dm_pkg.sv index b0f475c94..686dc16db 100644 --- a/src/debug/dm_pkg.sv +++ b/src/debug/dm_pkg.sv @@ -19,23 +19,20 @@ package dm; parameter logic [3:0] DbgVersion013 = 4'h2; // size of program buffer in junks of 32-bit words - parameter logic [4:0] ProgBufSize = 5'h4; + parameter logic [4:0] ProgBufSize = 5'h2; + + // TODO(zarubaf) This is hard-coded to two at the moment // amount of data count registers implemented - parameter logic [3:0] DataCount = 5'h0; + parameter logic [3:0] DataCount = 5'h2; // address to which a hart should jump when it was requested to halt parameter logic [63:0] HaltAddress = 64'h800; + parameter logic [63:0] ResumeAddress = HaltAddress + 4; + parameter logic [63:0] ExceptionAddress = HaltAddress + 8; - parameter DbgAddressBits = 12; - - parameter logic [DbgAddressBits-1:0] Halted = 'h100; - parameter logic [DbgAddressBits-1:0] Going = 'h104; - parameter logic [DbgAddressBits-1:0] Resuming = 'h108; - parameter logic [DbgAddressBits-1:0] Exception = 'h10C; - - // #define FLAGS 0x400 - // #define FLAG_GO 0 - // #define FLAG_RESUME 1 + // address where data0-15 is shadowed or if shadowed in a CSR + // address of the first CSR used for shadowing the data + parameter logic [11:0] DataAddr = 12'h380; // we are aligned with Rocket here // debug registers typedef enum logic [7:0] { @@ -153,6 +150,16 @@ package dm; logic [23:0] control; } command_t; + typedef struct packed { + logic zero1; + logic [22:20] aarsize; + logic zero0; + logic postexec; + logic transfer; + logic write; + logic [15:0] regno; + } ac_ar_cmd_t; + typedef struct packed { logic [31:28] xdebugver; logic [27:16] zero2; diff --git a/src/debug/dm_top.sv b/src/debug/dm_top.sv index 7d2c926a2..84f00ef96 100644 --- a/src/debug/dm_top.sv +++ b/src/debug/dm_top.sv @@ -55,13 +55,16 @@ module dm_top #( logic [NrHarts-1:0] haltreq; logic [NrHarts-1:0] resumereq; logic [NrHarts-1:0] ackhavereset; - logic command_write; - dm::command_t command; - logic [NrHarts-1:0] set_cmderror; + logic cmd_valid; + dm::command_t cmd; + + logic [NrHarts-1:0] cmderror_valid; dm::cmderr_t [NrHarts-1:0] cmderror; logic [NrHarts-1:0] cmdbusy; logic [dm::ProgBufSize-1:0][31:0] progbuf; - logic [dm::DataCount-1:0][31:0] data; + logic [dm::DataCount-1:0][31:0] data_csrs_mem; + logic [dm::DataCount-1:0][31:0] data_mem_csrs; + logic data_valid; dm_csrs #( .NrHarts(NrHarts) @@ -82,48 +85,30 @@ module dm_top #( .dmactive_o ( dmactive_o ), .hartinfo_i ( hartinfo ), .halted_i ( halted ), - .running_i ( running ), .unavailable_i ( unavailable ), .havereset_i ( havereset ), .resumeack_i ( resumeack ), .haltreq_o ( haltreq ), .resumereq_o ( resumereq ), .ackhavereset_o ( ackhavereset ), - .command_write_o ( command_write ), - .command_o ( command ), - .set_cmderror_i ( set_cmderror ), + .cmd_valid_o ( cmd_valid ), + .cmd_o ( cmd ), + .cmderror_valid_i ( cmderror_valid ), .cmderror_i ( cmderror ), .cmdbusy_i ( cmdbusy ), .progbuf_o ( progbuf ), - .data_o ( data ) + .data_i ( data_mem_csrs ), + .data_valid_i ( data_valid ), + .data_o ( data_csrs_mem ) ); - logic [NrHarts-1:0] ackhalt; + // TODO(zarubaf) take care of resetting + assign havereset = '1; + assign unavailable = '0; + // Debug Ctrl for each hart for (genvar i = 0; i < NrHarts; i++) begin : dm_hart_ctrl - assign hartinfo[i] = ariane_pkg::DebugHartInfo; - - dm_ctrl i_dm_ctrl ( - .clk_i ( clk_i ), - .dmactive_i ( dmactive_o ), - .ndmreset_i ( ndmreset_o ), - .debug_req_o ( debug_req_o [i] ), - .halted_o ( halted [i] ), - .running_o ( running [i] ), - .unavailable_o ( unavailable [i] ), - .havereset_o ( havereset [i] ), - .resumeack_o ( resumeack [i] ), - .haltreq_i ( haltreq ), - .resumereq_i ( resumereq ), - .ackhavereset_i ( ackhavereset ), - .command_write_i ( command_write ), - .command_i ( command ), - .set_cmderror_o ( set_cmderror [i] ), - .cmderror_o ( cmderror [i] ), - .cmdbusy_o ( cmdbusy [i] ), - .halted_i ( ackhalt [i] ) - ); end logic req; @@ -137,20 +122,31 @@ module dm_top #( dm_mem #( .NrHarts (NrHarts) ) i_dm_mem ( - .clk_i ( clk_i ), - .dmactive_i ( dmactive_o), - .halted_o ( ackhalt ), - .going_o ( ), - .resuming_o ( ), - .exception_o ( ), - .progbuf_i ( progbuf ), // program buffer to expose - .data_i ( data ), // data in - .req_i ( req ), - .we_i ( we ), - .addr_i ( addr ), - .wdata_i ( wdata ), - .be_i ( be ), - .rdata_o ( rdata ) + .clk_i ( clk_i ), + .dmactive_i ( dmactive_o ), + .debug_req_o ( debug_req_o ), + + .haltreq_i ( haltreq ), + .resumereq_i ( resumereq ), + .halted_o ( halted ), + .resuming_o ( resumeack ), + .cmd_valid_i ( cmd_valid ), + .cmd_i ( cmd ), + .cmderror_valid_o ( cmderror_valid ), + .cmderror_o ( cmderror ), + .cmdbusy_o ( cmdbusy ), + + .progbuf_i ( progbuf ), + .data_i ( data_csrs_mem ), + .data_o ( data_mem_csrs ), + .data_valid_o ( data_valid ), + + .req_i ( req ), + .we_i ( we ), + .addr_i ( addr ), + .wdata_i ( wdata ), + .be_i ( be ), + .rdata_o ( rdata ) ); axi2mem #(