mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 21:57:11 -04:00
Switch CDC implementation to safer variant
This commit is contained in:
parent
af3182b860
commit
9ab76b9243
11 changed files with 174 additions and 645 deletions
|
@ -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
|
||||
|
|
2
Makefile
2
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 \
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 )
|
||||
);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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] )
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue