diff --git a/Bender.yml b/Bender.yml index 0ebabaeec..47d21138b 100644 --- a/Bender.yml +++ b/Bender.yml @@ -9,7 +9,7 @@ dependencies: axi_node: { git: "git@iis-git.ee.ethz.ch:pulp-open/axi_node.git", version: 1.0.3 } axi_slice: { git: "git@iis-git.ee.ethz.ch:sasa/axi_slice.git", version: 1.1.2 } tech_cells_generic: { git: "git@iis-git.ee.ethz.ch:pulp-open/tech_cells_generic.git", rev: master } - common_cells: { git: "git@iis-git.ee.ethz.ch:sasa/common_cells.git", version: v1.7.0 } + common_cells: { git: "git@iis-git.ee.ethz.ch:sasa/common_cells.git", version: v1.7.4 } fpga-support: { git: "https://github.com/pulp-platform/fpga-support.git", version: v0.3.2 } sources: - include/riscv_pkg.sv diff --git a/Makefile b/Makefile index 2baf5f9a1..004b583aa 100755 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \ src/axi/src/axi_join.sv \ src/fpga-support/rtl/SyncSpRamBeNx64.sv \ src/common_cells/src/deprecated/generic_fifo.sv \ - src/common_cells/src/sync.sv \ + src/common_cells/src/cdc_2phase.sv \ src/common_cells/src/spill_register.sv \ src/common_cells/src/sync_wedge.sv \ src/common_cells/src/fifo_v2.sv \ diff --git a/src/ariane.sv b/src/ariane.sv index 44796f613..c6ebea356 100644 --- a/src/ariane.sv +++ b/src/ariane.sv @@ -26,7 +26,6 @@ module ariane #( )( input logic clk_i, input logic rst_ni, - input logic test_en_i, // enable all clock gates for testing // Core ID, Cluster ID and boot address are considered more or less static input logic [63:0] boot_addr_i, // reset boot address input logic [ 3:0] core_id_i, // core id in a multicore environment (reflected in a CSR) diff --git a/src/debug/dm_csrs.sv b/src/debug/dm_csrs.sv index 3622eb3ba..81a66b153 100644 --- a/src/debug/dm_csrs.sv +++ b/src/debug/dm_csrs.sv @@ -24,14 +24,11 @@ module dm_csrs #( input logic dmi_rst_ni, // Debug Module Interface reset, active-low input logic dmi_req_valid_i, output logic dmi_req_ready_o, - input logic [ 6:0] dmi_req_bits_addr_i, - input logic [ 1:0] dmi_req_bits_op_i, // 0 = nop, 1 = read, 2 = write - input logic [31:0] dmi_req_bits_data_i, + input dm::dmi_req_t dmi_req_i, // every request needs a response one cycle later output logic dmi_resp_valid_o, input logic dmi_resp_ready_i, - output logic [ 1:0] dmi_resp_bits_resp_o, - output logic [31:0] dmi_resp_bits_data_o, + output dm::dmi_resp_t dmi_resp_o, // global ctrl output logic ndmreset_o, // non-debug module reset, active-high output logic dmactive_o, // 1 -> debug-module is active, 0 -> synchronous re-set @@ -80,7 +77,7 @@ module dm_csrs #( // the amount of bits we need to represent all harts localparam HartSelLen = (NrHarts == 1) ? 1 : $clog2(NrHarts); dm::dtm_op_t dtm_op; - assign dtm_op = dm::dtm_op_t'(dmi_req_bits_op_i); + assign dtm_op = dm::dtm_op_t'(dmi_req_i.op); logic resp_queue_full; logic resp_queue_empty; @@ -121,7 +118,7 @@ module dm_csrs #( logic [NrHarts-1:0] selected_hart; // a successful response returns zero - assign dmi_resp_bits_resp_o = dm::DTM_SUCCESS; + assign dmi_resp_o.resp = dm::DTM_SUCCESS; assign dmi_resp_valid_o = ~resp_queue_empty; assign dmi_req_ready_o = ~resp_queue_full; assign resp_queue_push = dmi_req_valid_i & dmi_req_ready_o; @@ -197,14 +194,14 @@ module dm_csrs #( // reads if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_READ) begin - unique case ({1'b0, dmi_req_bits_addr_i}) inside + unique case ({1'b0, dmi_req_i.addr}) inside [(dm::Data0):DataEnd]: begin if (dm::DataCount > 0) begin - resp_queue_data = data_q[dmi_req_bits_addr_i[4:0]]; + resp_queue_data = data_q[dmi_req_i.addr[4:0]]; end if (!cmdbusy_i) begin // check whether we need to re-execute the command (just give a cmd_valid) - cmd_valid_o = abstractauto_q.autoexecdata[dmi_req_bits_addr_i[3:0] - dm::Data0]; + cmd_valid_o = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] - dm::Data0]; end end dm::DMControl: resp_queue_data = dmcontrol_q; @@ -215,10 +212,10 @@ module dm_csrs #( // command is read-only dm::Command: resp_queue_data = '0; [(dm::ProgBuf0):ProgBufEnd]: begin - resp_queue_data = progbuf_q[dmi_req_bits_addr_i[4:0]]; + resp_queue_data = progbuf_q[dmi_req_i.addr[4:0]]; if (!cmdbusy_i) begin // check whether we need to re-execute the command (just give a cmd_valid) - cmd_valid_o = abstractauto_q.autoexecprogbuf[dmi_req_bits_addr_i[3:0]]; + cmd_valid_o = abstractauto_q.autoexecprogbuf[dmi_req_i.addr[3:0]]; end end dm::HaltSum0: resp_queue_data = haltsum0; @@ -269,23 +266,23 @@ module dm_csrs #( // write if (dmi_req_ready_o && dmi_req_valid_i && dtm_op == dm::DTM_WRITE) begin - unique case (dm::dm_csr_t'({1'b0, dmi_req_bits_addr_i})) inside + unique case (dm::dm_csr_t'({1'b0, dmi_req_i.addr})) inside [(dm::Data0):DataEnd]: begin // attempts to write them while busy is set does not change their value if (!cmdbusy_i && dm::DataCount > 0) begin - data_d[dmi_req_bits_addr_i[4:0]] = dmi_req_bits_data_i; + data_d[dmi_req_i.addr[4:0]] = dmi_req_i.data; // check whether we need to re-execute the command (just give a cmd_valid) - cmd_valid_o = abstractauto_q.autoexecdata[dmi_req_bits_addr_i[3:0] - dm::Data0]; + cmd_valid_o = abstractauto_q.autoexecdata[dmi_req_i.addr[3:0] - dm::Data0]; end end dm::DMControl: begin automatic dm::dmcontrol_t dmcontrol; - dmcontrol = dm::dmcontrol_t'(dmi_req_bits_data_i); + dmcontrol = dm::dmcontrol_t'(dmi_req_i.data); // clear the havreset of the selected hart if (dmcontrol.ackhavereset) begin havereset_d[selected_hart] = 1'b0; end - dmcontrol_d = dmi_req_bits_data_i; + dmcontrol_d = dmi_req_i.data; end dm::DMStatus:; // write are ignored to R/O register dm::Hartinfo:; // hartinfo is R/O @@ -296,7 +293,7 @@ module dm_csrs #( // them. No abstract command is started until the value is // reset to 0. automatic dm::abstractcs_t a_abstractcs; - a_abstractcs = dm::abstractcs_t'(dmi_req_bits_data_i); + a_abstractcs = dm::abstractcs_t'(dmi_req_i.data); // reads during abstract command execution are not allowed if (!cmdbusy_i) begin cmderr_d = dm::cmderr_t'(~a_abstractcs.cmderr & cmderr_q); @@ -309,7 +306,7 @@ module dm_csrs #( // writes are ignored if a command is already busy if (!cmdbusy_i) begin cmd_valid_o = 1'b1; - command_d = dm::command_t'(dmi_req_bits_data_i); + command_d = dm::command_t'(dmi_req_i.data); // 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 @@ -319,7 +316,7 @@ module dm_csrs #( dm::AbstractAuto: begin // this field can only be written legally when there is no command executing if (!cmdbusy_i) begin - abstractauto_d = {dmi_req_bits_data_i[31:16], 4'b0, dmi_req_bits_data_i[11:0]}; + abstractauto_d = {dmi_req_i.data[31:16], 4'b0, dmi_req_i.data[11:0]}; end else if (cmderr_q == dm::CmdErrNone) begin cmderr_d = dm::CmdErrBusy; end @@ -327,10 +324,10 @@ module dm_csrs #( [(dm::ProgBuf0):ProgBufEnd]: begin // attempts to write them while busy is set does not change their value if (!cmdbusy_i) begin - progbuf_d[dmi_req_bits_addr_i[4:0]] = dmi_req_bits_data_i; + progbuf_d[dmi_req_i.addr[4:0]] = dmi_req_i.data; // check whether we need to re-execute the command (just give a cmd_valid) // this should probably throw an error if executed during another command was busy - cmd_valid_o = abstractauto_q.autoexecprogbuf[dmi_req_bits_addr_i[3:0]]; + cmd_valid_o = abstractauto_q.autoexecprogbuf[dmi_req_i.addr[3:0]]; end end dm::SBCS: begin @@ -338,7 +335,7 @@ module dm_csrs #( if (sbbusy_i) begin sbcs_d.sbbusyerror = 1'b1; end begin - automatic dm::sbcs_t sbcs = dm::sbcs_t'(dmi_req_bits_data_i); + automatic dm::sbcs_t sbcs = dm::sbcs_t'(dmi_req_i.data); sbcs_d = sbcs; // R/W1C sbcs_d.sbbusyerror = sbcs_q.sbbusyerror & (~sbcs.sbbusyerror); @@ -350,7 +347,7 @@ module dm_csrs #( if (sbbusy_i) begin sbcs_d.sbbusyerror = 1'b1; end begin - sbaddr_d[31:0] = dmi_req_bits_data_i; + sbaddr_d[31:0] = dmi_req_i.data; sbaddress_write_valid_o = (sbcs_q.sberror == '0); end end @@ -359,7 +356,7 @@ module dm_csrs #( if (sbbusy_i) begin sbcs_d.sbbusyerror = 1'b1; end begin - sbaddr_d[63:32] = dmi_req_bits_data_i; + sbaddr_d[63:32] = dmi_req_i.data; end end dm::SBData0: begin @@ -367,7 +364,7 @@ module dm_csrs #( if (sbbusy_i) begin sbcs_d.sbbusyerror = 1'b1; end begin - sbdata_d[31:0] = dmi_req_bits_data_i; + sbdata_d[31:0] = dmi_req_i.data; sbdata_write_valid_o = (sbcs_q.sberror == '0); end end @@ -376,7 +373,7 @@ module dm_csrs #( if (sbbusy_i) begin sbcs_d.sbbusyerror = 1'b1; end begin - sbdata_d[63:32] = dmi_req_bits_data_i; + sbdata_d[63:32] = dmi_req_i.data; end end default:; @@ -448,7 +445,7 @@ module dm_csrs #( assign data_o = data_q; assign resp_queue_pop = dmi_resp_ready_i & ~resp_queue_empty; - + // response FIFO fifo_v2 #( .dtype ( logic [31:0] ), @@ -464,7 +461,7 @@ module dm_csrs #( .alm_empty_o ( ), .data_i ( resp_queue_data ), .push_i ( resp_queue_push ), - .data_o ( dmi_resp_bits_data_o ), + .data_o ( dmi_resp_o.data ), .pop_i ( resp_queue_pop ) ); diff --git a/src/debug/dm_pkg.sv b/src/debug/dm_pkg.sv index 340e8a2ee..df7f9ff67 100644 --- a/src/debug/dm_pkg.sv +++ b/src/debug/dm_pkg.sv @@ -203,4 +203,15 @@ package dm; localparam logic[1:0] DTM_SUCCESS = 2'h0; + typedef struct packed { + logic [6:0] addr; + dtm_op_t op; + logic [31:0] data; + } dmi_req_t; + + typedef struct packed { + logic [31:0] data; + logic [1:0] resp; + } dmi_resp_t; + endpackage diff --git a/src/debug/dm_top.sv b/src/debug/dm_top.sv index fc935c7bd..e0fd5b3c6 100644 --- a/src/debug/dm_top.sv +++ b/src/debug/dm_top.sv @@ -38,14 +38,11 @@ module dm_top #( input logic dmi_rst_ni, input logic dmi_req_valid_i, output logic dmi_req_ready_o, - input logic [ 6:0] dmi_req_bits_addr_i, - input logic [ 1:0] dmi_req_bits_op_i, // 0 = nop, 1 = read, 2 = write - input logic [31:0] dmi_req_bits_data_i, + input dm::dmi_req_t dmi_req_i, output logic dmi_resp_valid_o, input logic dmi_resp_ready_i, - output logic [ 1:0] dmi_resp_bits_resp_o, - output logic [31:0] dmi_resp_bits_data_o + output dm::dmi_resp_t dmi_resp_o ); // Debug CSRs @@ -102,16 +99,13 @@ module dm_top #( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .testmode_i ( testmode_i ), - .dmi_rst_ni ( dmi_rst_ni ), - .dmi_req_valid_i ( dmi_req_valid_i ), - .dmi_req_ready_o ( dmi_req_ready_o ), - .dmi_req_bits_addr_i ( dmi_req_bits_addr_i ), - .dmi_req_bits_op_i ( dmi_req_bits_op_i ), - .dmi_req_bits_data_i ( dmi_req_bits_data_i ), - .dmi_resp_valid_o ( dmi_resp_valid_o ), - .dmi_resp_ready_i ( dmi_resp_ready_i ), - .dmi_resp_bits_resp_o ( dmi_resp_bits_resp_o ), - .dmi_resp_bits_data_o ( dmi_resp_bits_data_o ), + .dmi_rst_ni, + .dmi_req_valid_i, + .dmi_req_ready_o, + .dmi_req_i, + .dmi_resp_valid_o, + .dmi_resp_ready_i, + .dmi_resp_o, .ndmreset_o ( ndmreset_o ), .dmactive_o ( dmactive_o ), .hartsel_o ( hartsel ), diff --git a/src/debug/dmi_cdc.sv b/src/debug/dmi_cdc.sv index 4740f2e17..523d98a4f 100644 --- a/src/debug/dmi_cdc.sv +++ b/src/debug/dmi_cdc.sv @@ -18,510 +18,53 @@ */ module dmi_cdc ( // JTAG side (master side) - input logic tck_i, - input logic trst_ni, + input logic tck_i, + input logic trst_ni, - input logic mem_valid_i, - output logic mem_gnt_o, - input logic [6:0] mem_addr_i, - input logic mem_we_i, - input logic [31:0] mem_wdata_i, - output logic [31:0] mem_rdata_o, - output logic mem_rvalid_o, + input dm::dmi_req_t jtag_dmi_req_i, + output logic jtag_dmi_ready_o, + input logic jtag_dmi_valid_i, + output dm::dmi_resp_t jtag_dmi_resp_o, + output logic jtag_dmi_valid_o, + input logic jtag_dmi_ready_i, - // Memory -> Slave side - input logic clk_i, - input logic rst_ni, + // core side (slave side) + input logic clk_i, + input logic rst_ni, - output logic dmi_req_valid_o, - input logic dmi_req_ready_i, + output dm::dmi_req_t core_dmi_req_o, + output logic core_dmi_valid_o, + input logic core_dmi_ready_i, + input dm::dmi_resp_t core_dmi_resp_i, + output logic core_dmi_ready_o, + input logic core_dmi_valid_i + ); - output logic [ 6:0] dmi_req_bits_addr_o, - output logic [ 1:0] dmi_req_bits_op_o, - output logic [31:0] dmi_req_bits_data_o, + cdc_2phase #(.T(dm::dmi_req_t)) i_cdc_req ( + .src_rst_ni ( trst_ni ), + .src_clk_i ( tck_i ), + .src_data_i ( jtag_dmi_req_i ), + .src_valid_i ( jtag_dmi_valid_i ), + .src_ready_o ( jtag_dmi_ready_o ), - input logic dmi_resp_valid_i, - output logic dmi_resp_ready_o, - input logic [ 1:0] dmi_resp_bits_resp_i, - input logic [31:0] dmi_resp_bits_data_i -); + .dst_rst_ni ( rst_ni ), + .dst_clk_i ( clk_i ), + .dst_data_o ( core_dmi_valid_o ), + .dst_valid_o ( core_dmi_valid_o ), + .dst_ready_i ( core_dmi_ready_i ) + ); - logic mem_we; - // we will always be ready to receive the request we made - assign dmi_resp_ready_o = 1'b1; - // very "cheap" protocol conversion - assign dmi_req_bits_op_o = (mem_we) ? dm::DTM_WRITE : dm::DTM_READ; + cdc_2phase #(.T(dm::dmi_resp_t)) i_cdc_resp ( + .src_rst_ni ( rst_ni ), + .src_clk_i ( clk_i ), + .src_data_i ( core_dmi_resp_i ), + .src_valid_i ( core_dmi_valid_i ), + .src_ready_o ( core_dmi_ready_o ), - localparam int unsigned AddrWidth = 7; - localparam int unsigned DataWidth = 32; - - logic cdc_req_a; - logic cdc_ack_a; - logic [AddrWidth-1:0] cdc_addr_a; - logic cdc_we_a; - logic [DataWidth/8-1:0] cdc_be_a; - logic [DataWidth-1:0] cdc_wdata_a; - logic cdc_clear_a; - logic cdc_rreq_a; - logic cdc_rack_a; - logic [DataWidth-1:0] cdc_rdata_a; - logic cdc_rerror_a; - - // lets re-use most of the debug facilities which are already in PULP - dmi_cdc_jtag #( - .ADDR_WIDTH (AddrWidth), - .DATA_WIDTH (DataWidth) - ) i_dmi_cdc_jtag ( - .tck_i, - .trst_ni, - .mem_req_i ( mem_valid_i ), - .mem_gnt_o, - .mem_addr_i, - .mem_we_i, - .mem_be_i ( '1 ), - .mem_wdata_i, - .mem_rdata_o, - .mem_rvalid_o, - // we are not managing any errors here - // a more elaborate implementation should probably handle this more gracefully - .mem_rerror_o ( ), - .mem_clear_i ( 1'b0 ), - .cdc_req_ao ( cdc_req_a ), - .cdc_ack_ai ( cdc_ack_a ), - .cdc_addr_ao ( cdc_addr_a ), - .cdc_we_ao ( cdc_we_a ), - .cdc_be_ao ( cdc_be_a ), - .cdc_wdata_ao ( cdc_wdata_a ), - .cdc_clear_ao ( cdc_clear_a ), - .cdc_rreq_ai ( cdc_rreq_a ), - .cdc_rack_ao ( cdc_rack_a ), - .cdc_rdata_ai ( cdc_rdata_a ), - .cdc_rerror_ai ( cdc_rerror_a ) - ); - - dmi_cdc_mem #( - .ADDR_WIDTH (AddrWidth), - .DATA_WIDTH (DataWidth) - ) i_dmi_cdc_mem ( - .clk_i, - .rst_ni, - .mem_req_o ( dmi_req_valid_o ), - .mem_gnt_i ( dmi_req_ready_i ), - .mem_addr_o ( dmi_req_bits_addr_o ), - .mem_we_o ( mem_we ), - // don't care we always write whole words - .mem_be_o ( ), - .mem_wdata_o ( dmi_req_bits_data_o ), - .mem_rdata_i ( dmi_resp_bits_data_i ), - .mem_rvalid_i ( dmi_resp_valid_i ), - // don't care about clearing an error flag - // that is handled differently in the RISC-V implementation - .mem_rerror_i ( 1'b0 ), - .mem_clear_o ( ), - .cdc_req_ai ( cdc_req_a ), - .cdc_ack_ao ( cdc_ack_a ), - .cdc_addr_ai ( cdc_addr_a ), - .cdc_we_ai ( cdc_we_a ), - .cdc_be_ai ( cdc_be_a ), - .cdc_wdata_ai ( cdc_wdata_a ), - .cdc_clear_ai ( cdc_clear_a ), - .cdc_rreq_ao ( cdc_rreq_a ), - .cdc_rack_ai ( cdc_rack_a ), - .cdc_rdata_ao ( cdc_rdata_a ), - .cdc_rerror_ao ( cdc_rerror_a ) - ); -endmodule - -module dmi_cdc_jtag #( - parameter int unsigned ADDR_WIDTH = 32, - parameter int unsigned DATA_WIDTH = 64 -)( - // JTAG side - input logic tck_i, - input logic trst_ni, - - input logic mem_req_i, - output logic mem_gnt_o, - input logic [ADDR_WIDTH-1:0] mem_addr_i, - input logic mem_we_i, - input logic [DATA_WIDTH/8-1:0] mem_be_i, - input logic [DATA_WIDTH-1:0] mem_wdata_i, - output logic [DATA_WIDTH-1:0] mem_rdata_o, - output logic mem_rvalid_o, - output logic mem_rerror_o, - - input logic mem_clear_i, - - // CDC side - output logic cdc_req_ao, - input logic cdc_ack_ai, - output logic [ADDR_WIDTH-1:0] cdc_addr_ao, - output logic cdc_we_ao, - output logic [DATA_WIDTH/8-1:0] cdc_be_ao, - output logic [DATA_WIDTH-1:0] cdc_wdata_ao, - output logic cdc_clear_ao, - input logic cdc_rreq_ai, - output logic cdc_rack_ao, - input logic [DATA_WIDTH-1:0] cdc_rdata_ai, - input logic cdc_rerror_ai - ); - - enum logic [1:0] { IDLE, WAIT_ACK_LOW, WAIT_ACK_HIGH, READY_ACK_LOW } req_state_p, req_state_n; - enum logic [0:0] { RIDLE, WAIT_REQ_LOW } resp_state_p, resp_state_n; - - logic [ADDR_WIDTH-1:0] cdc_addr_p; - logic cdc_we_p; - logic [DATA_WIDTH/8-1:0] cdc_be_p; - logic [DATA_WIDTH-1:0] cdc_wdata_p; - - logic cdc_req_n; - - logic cdc_clear_p; - - logic cdc_ack; - logic cdc_rreq; - - always_comb - begin - req_state_n = req_state_p; - - mem_gnt_o = 1'b0; - cdc_req_n = 1'b0; - - unique case (req_state_p) - IDLE: begin - if (mem_req_i) begin - req_state_n = WAIT_ACK_HIGH; - - mem_gnt_o = 1'b1; - end - end - - WAIT_ACK_HIGH: begin - cdc_req_n = 1'b1; - - if (cdc_ack) begin - req_state_n = WAIT_ACK_LOW; - end - end - - WAIT_ACK_LOW: begin - if (mem_req_i) - mem_gnt_o = 1'b1; - - if (~cdc_ack) begin - if (mem_req_i) - req_state_n = WAIT_ACK_HIGH; - else - req_state_n = IDLE; - end else begin - if (mem_req_i) - req_state_n = READY_ACK_LOW; - end - end - - READY_ACK_LOW: begin - if (~cdc_ack) begin - req_state_n = WAIT_ACK_HIGH; - end - end - - default:; // make unique case happy during reset - endcase - end - - always_comb - begin - resp_state_n = resp_state_p; - - mem_rvalid_o = 1'b0; - cdc_rack_ao = 1'b0; - - unique case (resp_state_p) - RIDLE: begin - if (cdc_rreq) begin - resp_state_n = WAIT_REQ_LOW; - mem_rvalid_o = 1'b1; - end - end - - WAIT_REQ_LOW: begin - cdc_rack_ao = 1'b1; - - if (~cdc_rreq) begin - resp_state_n = RIDLE; - end - end - - default:; // make unique case happy during reset - endcase - end - - always_ff @(posedge tck_i, negedge trst_ni) begin - if (~trst_ni) begin - req_state_p <= IDLE; - resp_state_p <= RIDLE; - - cdc_addr_p <= '0; - cdc_we_p <= '0; - cdc_be_p <= '0; - cdc_wdata_p <= '0; - cdc_clear_p <= '0; - cdc_req_ao <= 1'b0; - end else begin - req_state_p <= req_state_n; - resp_state_p <= resp_state_n; - cdc_req_ao <= cdc_req_n; - - if (mem_gnt_o) begin - cdc_addr_p <= mem_addr_i; - cdc_we_p <= mem_we_i; - cdc_be_p <= mem_be_i; - cdc_wdata_p <= mem_wdata_i; - cdc_clear_p <= mem_clear_i; - end - end - end - - assign cdc_addr_ao = cdc_addr_p; - assign cdc_we_ao = cdc_we_p; - assign cdc_be_ao = cdc_be_p; - assign cdc_wdata_ao = cdc_wdata_p; - assign cdc_clear_ao = cdc_clear_p; - - (* ASYNC_REG = "TRUE" *) - sync i_sync_ack ( - .clk_i ( tck_i ), - .rst_ni ( trst_ni ) , - .serial_i ( cdc_ack_ai ), - .serial_o ( cdc_ack ) - ); - - (* ASYNC_REG = "TRUE" *) - sync i_sync_rreq ( - .clk_i ( tck_i ), - .rst_ni ( trst_ni ) , - .serial_i ( cdc_rreq_ai ), - .serial_o ( cdc_rreq ) - ); - - assign mem_rerror_o = cdc_rerror_ai; - assign mem_rdata_o = cdc_rdata_ai; - -endmodule - -module dmi_cdc_mem #( - parameter int unsigned ADDR_WIDTH = 32, - parameter int unsigned DATA_WIDTH = 64 -)( - // mem side - input logic clk_i, - input logic rst_ni, - - output logic mem_req_o, - input logic mem_gnt_i, - output logic [ADDR_WIDTH-1:0] mem_addr_o, - output logic mem_we_o, - output logic [DATA_WIDTH/8-1:0] mem_be_o, - output logic [DATA_WIDTH-1:0] mem_wdata_o, - input logic [DATA_WIDTH-1:0] mem_rdata_i, - input logic mem_rvalid_i, - input logic mem_rerror_i, - output logic mem_clear_o, - - // CDC side - input logic cdc_req_ai, - output logic cdc_ack_ao, - input logic [ADDR_WIDTH-1:0] cdc_addr_ai, - input logic cdc_we_ai, - input logic [DATA_WIDTH/8-1:0] cdc_be_ai, - input logic [DATA_WIDTH-1:0] cdc_wdata_ai, - input logic cdc_clear_ai, - - output logic cdc_rreq_ao, - input logic cdc_rack_ai, - output logic [DATA_WIDTH-1:0] cdc_rdata_ao, - output logic cdc_rerror_ao - ); - - enum logic [1:0] { IDLE, REQUEST, WAIT_REQ_LOW } req_state_p, req_state_n; - enum logic [1:0] { RIDLE, WAIT_ACK_HIGH, WAIT_ACK_LOW } resp_state_p, resp_state_n; - - logic [ADDR_WIDTH-1:0] mem_addr_p; - logic mem_we_p; - logic [DATA_WIDTH/8-1:0] mem_be_p; - logic [DATA_WIDTH-1:0] mem_wdata_p; - logic mem_clear_p; - - logic cdc_req; - logic cdc_clear; - logic cdc_sample; - - logic cdc_rack; - logic [DATA_WIDTH-1:0] cdc_rdata_p; - logic cdc_rerror_p; - - logic cdc_rreq_n; - logic cdc_ack_n; - - always_comb begin - req_state_n = req_state_p; - - cdc_ack_n = 1'b0; - cdc_sample = 1'b0; - - mem_req_o = 1'b0; - - unique case (req_state_p) - IDLE: begin - if (cdc_req) begin - req_state_n = REQUEST; - cdc_sample = 1'b1; - end - end - - REQUEST: begin - mem_req_o = 1'b1; - cdc_ack_n = 1'b1; - - if (mem_gnt_i) begin - req_state_n = WAIT_REQ_LOW; - end - end - - WAIT_REQ_LOW: begin - cdc_ack_n = 1'b1; - - if (~cdc_req) begin - req_state_n = IDLE; - end - end - - default:; // make unique case happy during reset - endcase - - if (cdc_clear) - req_state_n = IDLE; - end - - always_comb begin - resp_state_n = resp_state_p; - cdc_rreq_n = 1'b0; - - unique case (resp_state_p) - RIDLE: begin - if (mem_rvalid_i) begin - resp_state_n = WAIT_ACK_HIGH; - end - end - - WAIT_ACK_HIGH: begin - cdc_rreq_n = 1'b1; - - if (cdc_rack) begin - resp_state_n = WAIT_ACK_LOW; - end - end - - WAIT_ACK_LOW: begin - cdc_rreq_n = 1'b0; - - if (~cdc_rack) begin - resp_state_n = RIDLE; - end - end - - default:; // make unique case happy during reset - endcase - - if (cdc_clear) - resp_state_n = RIDLE; - end - - always_ff @(posedge clk_i, negedge rst_ni) begin - if (~rst_ni) begin - req_state_p <= IDLE; - resp_state_p <= RIDLE; - - mem_addr_p <= '0; - mem_we_p <= '0; - mem_be_p <= '0; - mem_wdata_p <= '0; - mem_clear_p <= '0; - - cdc_rdata_p <= '0; - cdc_rerror_p <= '0; - cdc_rreq_ao <= 1'b0; - cdc_ack_ao <= 1'b0; - end else begin - req_state_p <= req_state_n; - resp_state_p <= resp_state_n; - cdc_rreq_ao <= cdc_rreq_n; - cdc_ack_ao <= cdc_ack_n; - - if (cdc_sample) begin - mem_addr_p <= cdc_addr_ai; - mem_we_p <= cdc_we_ai; - mem_be_p <= cdc_be_ai; - mem_wdata_p <= cdc_wdata_ai; - mem_clear_p <= cdc_clear_ai; - end else begin - mem_clear_p <= '0; - end - - if (mem_rvalid_i) begin - cdc_rdata_p <= mem_rdata_i; - cdc_rerror_p <= mem_rerror_i; - end - end - end - - assign mem_addr_o = mem_addr_p; - assign mem_we_o = mem_we_p; - assign mem_be_o = mem_be_p; - assign mem_wdata_o = mem_wdata_p; - assign mem_clear_o = mem_clear_p; - - assign cdc_rdata_ao = cdc_rdata_p; - assign cdc_rerror_ao = cdc_rerror_p; - - (* ASYNC_REG = "TRUE" *) - sync i_sync_req ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ) , - .serial_i ( cdc_req_ai ), - .serial_o ( cdc_req ) - ); - - (* ASYNC_REG = "TRUE" *) - sync i_sync_clear ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - .serial_i ( cdc_clear_ai ), - .serial_o ( cdc_clear ) - ); - - (* ASYNC_REG = "TRUE" *) - sync i_sync_rack ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ) , - .serial_i ( cdc_rack_ai ), - .serial_o ( cdc_rack ) - ); - - //---------------------------------------------------------------------------- - // Assertions - //---------------------------------------------------------------------------- - -`ifndef SYNTHESIS -`ifndef verilator - assert property ( - @(posedge clk_i) (mem_req_o) |-> (!$isunknown(mem_addr_o) && !$isunknown(mem_we_o) - && !$isunknown(mem_be_o) && !$isunknown(mem_wdata_o))) - else $warning("mem request data may never be unknown"); - - assert property ( - @(posedge clk_i) (!$isunknown(mem_gnt_i))) else $warning("memory grant may never be unknown"); -`endif -`endif + .dst_rst_ni ( trst_ni ), + .dst_clk_i ( tck_i ), + .dst_data_o ( jtag_dmi_resp_o ), + .dst_valid_o ( jtag_dmi_valid_o ), + .dst_ready_i ( jtag_dmi_ready_i ) + ); endmodule diff --git a/src/debug/dmi_jtag.sv b/src/debug/dmi_jtag.sv index dc4c9859d..430ccae51 100644 --- a/src/debug/dmi_jtag.sv +++ b/src/debug/dmi_jtag.sv @@ -17,27 +17,25 @@ */ module dmi_jtag ( - input logic clk_i, // DMI Clock - input logic rst_ni, // Asynchronous reset active low + input logic clk_i, // DMI Clock + input logic rst_ni, // Asynchronous reset active low - output logic dmi_rst_no, // hard reset + output logic dmi_rst_no, // hard reset - output logic dmi_req_valid_o, - input logic dmi_req_ready_i, - output logic [ 6:0] dmi_req_bits_addr_o, - output logic [ 1:0] dmi_req_bits_op_o, // 0 = nop, 1 = read, 2 = write - output logic [31:0] dmi_req_bits_data_o, - input logic dmi_resp_valid_i, - output logic dmi_resp_ready_o, - input logic [ 1:0] dmi_resp_bits_resp_i, - input logic [31:0] dmi_resp_bits_data_i, + output dm::dmi_req_t dmi_req_o, + output logic dmi_req_valid_o, + input logic dmi_req_ready_i, - input logic tck_i, // JTAG test clock pad - input logic tms_i, // JTAG test mode select pad - input logic trst_ni, // JTAG test reset pad - input logic td_i, // JTAG test data input pad - output logic td_o, // JTAG test data output pad - output logic tdo_oe_o // Data out output enable + input dm::dmi_resp_t dmi_resp_i, + output logic dmi_resp_ready_o, + input logic dmi_resp_valid_i, + + input logic tck_i, // JTAG test clock pad + input logic tms_i, // JTAG test mode select pad + input logic trst_ni, // JTAG test reset pad + input logic td_i, // JTAG test data input pad + output logic td_o, // JTAG test data output pad + output logic tdo_oe_o // Data out output enable ); assign dmi_rst_no = 1'b1; @@ -51,13 +49,13 @@ module dmi_jtag ( logic dmi_tdi; logic dmi_tdo; - logic mem_valid; - logic mem_gnt; - logic [6:0] mem_addr; - logic mem_we; - logic [31:0] mem_wdata; - logic [31:0] mem_rdata; - logic mem_rvalid; + dm::dmi_req_t dmi_req; + logic dmi_req_ready; + logic dmi_req_valid; + + dm::dmi_resp_t dmi_resp; + logic dmi_resp_valid; + logic dmi_resp_ready; typedef struct packed { logic [6:0] address; @@ -77,10 +75,12 @@ module dmi_jtag ( logic [31:0] data_d, data_q; dmi_t dmi; - assign dmi = dmi_t'(dr_q); - assign mem_addr = address_q; - assign mem_wdata = data_q; - assign mem_we = (state_q == Write); + assign dmi = dmi_t'(dr_q); + assign dmi_req.addr = address_q; + assign dmi_req.data = data_q; + assign dmi_req.op = (state_q == Write) ? dm::DTM_WRITE : dm::DTM_READ; + // we'will always be ready to accept the data we requested + assign dmi_resp_ready = 1'b1; logic error_dmi_busy; dmi_error_t error_d, error_q; @@ -93,7 +93,7 @@ module dmi_jtag ( data_d = data_q; error_d = error_q; - mem_valid = 1'b0; + dmi_req_valid = 1'b0; case (state_q) Idle: begin @@ -112,31 +112,31 @@ module dmi_jtag ( end Read: begin - mem_valid = 1'b1; - if (mem_gnt) begin + dmi_req_valid = 1'b1; + if (dmi_req_ready) begin state_d = WaitReadValid; end end WaitReadValid: begin // load data into register and shift out - if (mem_rvalid) begin - data_d = mem_rdata; + if (dmi_resp_valid) begin + data_d = dmi_resp.data; state_d = Idle; end end Write: begin - mem_valid = 1'b1; + dmi_req_valid = 1'b1; // got a valid answer go back to idle - if (mem_gnt) begin + if (dmi_req_ready) begin state_d = Idle; end end WaitWriteValid: begin // just wait for idle here - if (mem_rvalid) begin + if (dmi_resp_valid) begin state_d = Idle; end end @@ -237,26 +237,21 @@ module dmi_jtag ( // JTAG side (master side) .tck_i, .trst_ni, - - .mem_valid_i ( mem_valid ), - .mem_gnt_o ( mem_gnt ), - .mem_addr_i ( mem_addr ), - .mem_we_i ( mem_we ), - .mem_wdata_i ( mem_wdata ), - .mem_rdata_o ( mem_rdata ), - .mem_rvalid_o ( mem_rvalid ), - + .jtag_dmi_req_i ( dmi_req ), + .jtag_dmi_ready_o ( dmi_req_ready ), + .jtag_dmi_valid_i ( dmi_req_valid ), + .jtag_dmi_resp_o ( dmi_resp ), + .jtag_dmi_valid_o ( dmi_resp_valid ), + .jtag_dmi_ready_i ( dmi_resp_ready ), + // core side .clk_i, .rst_ni, - .dmi_req_valid_o, - .dmi_req_ready_i, - .dmi_req_bits_addr_o, - .dmi_req_bits_op_o, - .dmi_req_bits_data_o, - .dmi_resp_valid_i, - .dmi_resp_ready_o, - .dmi_resp_bits_resp_i, - .dmi_resp_bits_data_i + .core_dmi_req_o ( dmi_req_o ), + .core_dmi_valid_o ( dmi_req_valid_o ), + .core_dmi_ready_i ( dmi_req_ready_i ), + .core_dmi_resp_i ( dmi_resp_i ), + .core_dmi_ready_o ( dmi_resp_ready_o ), + .core_dmi_valid_i ( dmi_resp_valid_i ) ); endmodule diff --git a/src/issue_read_operands.sv b/src/issue_read_operands.sv index 8cf5e990c..b6c0949fc 100644 --- a/src/issue_read_operands.sv +++ b/src/issue_read_operands.sv @@ -20,7 +20,6 @@ module issue_read_operands #( )( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low - input logic test_en_i, // flush input logic flush_i, // coming from rename @@ -282,7 +281,7 @@ module issue_read_operands #( // Clock and Reset .clk ( clk_i ), .rst_n ( rst_ni ), - .test_en_i ( test_en_i ), + .test_en_i ( 1'b0 ), .raddr_a_i ( issue_instr_i.rs1[4:0] ), .rdata_a_o ( operand_a_regfile ), diff --git a/src/issue_stage.sv b/src/issue_stage.sv index 560c80875..2a8d01871 100644 --- a/src/issue_stage.sv +++ b/src/issue_stage.sv @@ -22,7 +22,6 @@ module issue_stage #( )( input logic clk_i, // Clock input logic rst_ni, // Asynchronous reset active low - input logic test_en_i, // Test Enable input logic flush_unissued_instr_i, input logic flush_i, diff --git a/tb/ariane_testharness.sv b/tb/ariane_testharness.sv index fc611c4da..df695010d 100644 --- a/tb/ariane_testharness.sv +++ b/tb/ariane_testharness.sv @@ -30,7 +30,7 @@ module ariane_testharness #( logic test_en; logic ndmreset; logic ndmreset_n; - logic debug_req; + logic debug_req_core; int jtag_enable; logic init_done; @@ -45,9 +45,6 @@ module ariane_testharness #( logic debug_req_valid; logic debug_req_ready; - logic [6:0] debug_req_bits_addr; - logic [1:0] debug_req_bits_op; - logic [31:0] debug_req_bits_data; logic debug_resp_valid; logic debug_resp_ready; logic [1:0] debug_resp_bits_resp; @@ -98,12 +95,16 @@ module ariane_testharness #( if (!$value$plusargs("jtag_rbb_enable=%b", jtag_enable)) jtag_enable = 'h0; end + dm::dmi_req_t jtag_dmi_req; + dm::dmi_req_t dmi_req; + + dm::dmi_req_t debug_req; + dm::dmi_resp_t debug_resp; + // debug if MUX assign debug_req_valid = (jtag_enable[0]) ? jtag_req_valid : dmi_req_valid; - assign debug_req_bits_addr = (jtag_enable[0]) ? jtag_req_bits_addr : dmi_req_bits_addr; - assign debug_req_bits_op = (jtag_enable[0]) ? jtag_req_bits_op : dmi_req_bits_op; - assign debug_req_bits_data = (jtag_enable[0]) ? jtag_req_bits_data : dmi_req_bits_data; assign debug_resp_ready = (jtag_enable[0]) ? jtag_resp_ready : dmi_resp_ready; + assign debug_req = (jtag_enable[0]) ? jtag_dmi_req : dmi_req; assign exit_o = (jtag_enable[0]) ? jtag_exit : dmi_exit; assign jtag_resp_valid = (jtag_enable[0]) ? debug_resp_valid : 1'b0; assign dmi_resp_valid = (jtag_enable[0]) ? 1'b0 : debug_resp_valid; @@ -125,26 +126,21 @@ module ariane_testharness #( ); dmi_jtag i_dmi_jtag ( - .clk_i ( clk_i ), - .rst_ni ( rst_ni ), - - .dmi_rst_no ( ), - .dmi_req_valid_o ( jtag_req_valid ), - .dmi_req_ready_i ( debug_req_ready ), - .dmi_req_bits_addr_o ( jtag_req_bits_addr ), - .dmi_req_bits_op_o ( jtag_req_bits_op ), - .dmi_req_bits_data_o ( jtag_req_bits_data ), - .dmi_resp_valid_i ( jtag_resp_valid ), - .dmi_resp_ready_o ( jtag_resp_ready ), - .dmi_resp_bits_resp_i ( debug_resp_bits_resp ), - .dmi_resp_bits_data_i ( debug_resp_bits_data ), - - .tck_i ( jtag_TCK ), - .tms_i ( jtag_TMS ), - .trst_ni ( jtag_TRSTn ), - .td_i ( jtag_TDI ), - .td_o ( jtag_TDO_data ), - .tdo_oe_o ( jtag_TDO_driven ) + .clk_i ( clk_i ), + .rst_ni ( rst_ni ), + .dmi_req_o ( jtag_dmi_req ), + .dmi_req_valid_o ( jtag_req_valid ), + .dmi_req_ready_i ( debug_req_ready ), + .dmi_resp_i ( debug_resp ), + .dmi_resp_ready_o ( jtag_resp_ready ), + .dmi_resp_valid_i ( jtag_resp_valid ), + .dmi_rst_no ( ), // not connected + .tck_i ( jtag_TCK ), + .tms_i ( jtag_TMS ), + .trst_ni ( jtag_TRSTn ), + .td_i ( jtag_TDI ), + .td_o ( jtag_TDO_data ), + .tdo_oe_o ( jtag_TDO_driven ) ); // SiFive's SimDTM Module @@ -154,13 +150,13 @@ module ariane_testharness #( .reset ( ~rst_ni ), .debug_req_valid ( dmi_req_valid ), .debug_req_ready ( debug_req_ready ), - .debug_req_bits_addr ( dmi_req_bits_addr ), - .debug_req_bits_op ( dmi_req_bits_op ), - .debug_req_bits_data ( dmi_req_bits_data ), + .debug_req_bits_addr ( dmi_req.addr ), + .debug_req_bits_op ( dmi_req.op ), + .debug_req_bits_data ( dmi_req.data ), .debug_resp_valid ( dmi_resp_valid ), .debug_resp_ready ( dmi_resp_ready ), - .debug_resp_bits_resp ( debug_resp_bits_resp ), - .debug_resp_bits_data ( debug_resp_bits_data ), + .debug_resp_bits_resp ( debug_resp.resp ), + .debug_resp_bits_data ( debug_resp.data ), .exit ( dmi_exit ) ); @@ -178,20 +174,17 @@ module ariane_testharness #( .testmode_i ( test_en ), .ndmreset_o ( ndmreset ), .dmactive_o ( ), // active debug session - .debug_req_o ( debug_req ), + .debug_req_o ( debug_req_core ), .unavailable_i ( '0 ), .axi_master ( slave[3] ), .axi_slave ( master[3] ), .dmi_rst_ni ( rst_ni ), .dmi_req_valid_i ( debug_req_valid ), .dmi_req_ready_o ( debug_req_ready ), - .dmi_req_bits_addr_i ( debug_req_bits_addr ), - .dmi_req_bits_op_i ( debug_req_bits_op ), - .dmi_req_bits_data_i ( debug_req_bits_data ), + .dmi_req_i ( debug_req ), .dmi_resp_valid_o ( debug_resp_valid ), .dmi_resp_ready_i ( debug_resp_ready ), - .dmi_resp_bits_resp_o ( debug_resp_bits_resp ), - .dmi_resp_bits_data_o ( debug_resp_bits_data ) + .dmi_resp_o ( debug_resp ) ); // --------------- @@ -303,7 +296,7 @@ module ariane_testharness #( .clk_i ( clk_i ), .rst_ni ( rst_ni ), .slave ( master[1] ), - .rtc_i ( 1'b0 ), + .rtc_i ( 1'b0 ), .timer_irq_o ( timer_irq ), .ipi_o ( ipi ) ); @@ -318,14 +311,13 @@ module ariane_testharness #( ) i_ariane ( .clk_i ( clk_i ), .rst_ni ( ndmreset_n ), - .test_en_i ( test_en ), .boot_addr_i ( 64'h10000 ), // start fetching from ROM .core_id_i ( '0 ), .cluster_id_i ( '0 ), .irq_i ( '0 ), // we do not specify other interrupts in this TB .ipi_i ( ipi ), .time_irq_i ( timer_irq ), - .debug_req_i ( debug_req ), + .debug_req_i ( debug_req_core ), .data_if ( slave[2] ), .bypass_if ( slave[1] ), .instr_if ( slave[0] )