mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 05:07:21 -04:00
Exchange axi interfaces with structs in CLINT and DM interfaces.
This commit is contained in:
parent
fcba756c39
commit
3dd9ac57a9
10 changed files with 358 additions and 130 deletions
5
Makefile
5
Makefile
|
@ -82,7 +82,10 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \
|
|||
src/common_cells/src/rstgen_bypass.sv \
|
||||
src/common_cells/src/stream_mux.sv \
|
||||
src/common_cells/src/stream_demux.sv \
|
||||
src/util/axi_connect.sv \
|
||||
src/util/axi_master_connect.sv \
|
||||
src/util/axi_slave_connect.sv \
|
||||
src/util/axi_master_connect_rev.sv \
|
||||
src/util/axi_slave_connect_rev.sv \
|
||||
src/axi/src/axi_cut.sv \
|
||||
src/axi/src/axi_join.sv \
|
||||
src/fpga-support/rtl/SyncSpRamBeNx64.sv \
|
||||
|
|
|
@ -21,7 +21,8 @@ module axi_lite_interface #(
|
|||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
|
||||
AXI_BUS.Slave slave,
|
||||
input ariane_axi::req_t axi_req_i,
|
||||
output ariane_axi::resp_t axi_resp_o,
|
||||
|
||||
output logic [AXI_ADDR_WIDTH-1:0] address_o,
|
||||
output logic en_o, // transaction is valid
|
||||
|
@ -38,17 +39,17 @@ module axi_lite_interface #(
|
|||
logic [AXI_ADDR_WIDTH-1:0] address_n, address_q;
|
||||
|
||||
// pass through read data on the read data channel
|
||||
assign slave.r_data = data_i;
|
||||
assign axi_resp_o.r.data = data_i;
|
||||
// send back the transaction id we've latched
|
||||
assign slave.r_id = trans_id_q;
|
||||
assign slave.b_id = trans_id_q;
|
||||
assign axi_resp_o.r.id = trans_id_q;
|
||||
assign axi_resp_o.b.id = trans_id_q;
|
||||
// set r_last to one as defined by the AXI4 - Lite standard
|
||||
assign slave.r_last = 1'b1;
|
||||
assign axi_resp_o.r.last = 1'b1;
|
||||
// we do not support any errors so set response flag to all zeros
|
||||
assign slave.b_resp = 2'b0;
|
||||
assign slave.r_resp = 2'b0;
|
||||
assign axi_resp_o.b.resp = 2'b0;
|
||||
assign axi_resp_o.r.resp = 2'b0;
|
||||
// output data which we want to write to the slave
|
||||
assign data_o = slave.w_data;
|
||||
assign data_o = axi_req_i.w.data;
|
||||
// ------------------------
|
||||
// AXI4-Lite State Machine
|
||||
// ------------------------
|
||||
|
@ -59,12 +60,12 @@ module axi_lite_interface #(
|
|||
trans_id_n = trans_id_q;
|
||||
|
||||
// we'll answer a write request only if we got address and data
|
||||
slave.aw_ready = 1'b0;
|
||||
slave.w_ready = 1'b0;
|
||||
slave.b_valid = 1'b0;
|
||||
axi_resp_o.aw_ready = 1'b0;
|
||||
axi_resp_o.w_ready = 1'b0;
|
||||
axi_resp_o.b_valid = 1'b0;
|
||||
|
||||
slave.ar_ready = 1'b1;
|
||||
slave.r_valid = 1'b0;
|
||||
axi_resp_o.ar_ready = 1'b1;
|
||||
axi_resp_o.r_valid = 1'b0;
|
||||
|
||||
address_o = '0;
|
||||
we_o = 1'b0;
|
||||
|
@ -74,24 +75,24 @@ module axi_lite_interface #(
|
|||
// we are ready to accept a new request
|
||||
IDLE: begin
|
||||
// we've git a valid write request, we also know that we have asserted the aw_ready
|
||||
if (slave.aw_valid) begin
|
||||
if (axi_req_i.aw_valid) begin
|
||||
|
||||
slave.aw_ready = 1'b1;
|
||||
axi_resp_o.aw_ready = 1'b1;
|
||||
// this costs performance but the interconnect does not obey the AXI standard
|
||||
NS = WRITE;
|
||||
// save address
|
||||
address_n = slave.aw_addr;
|
||||
address_n = axi_req_i.aw.addr;
|
||||
// save the transaction id for reflection
|
||||
trans_id_n = slave.aw_id;
|
||||
trans_id_n = axi_req_i.aw.id;
|
||||
|
||||
// we've got a valid read request, we also know that we have asserted the ar_ready
|
||||
end else if (slave.ar_valid) begin
|
||||
end else if (axi_req_i.ar_valid) begin
|
||||
NS = READ;
|
||||
address_n = slave.ar_addr;
|
||||
address_n = axi_req_i.ar.addr;
|
||||
// also request the word from the memory-like interface
|
||||
address_o = slave.ar_addr;
|
||||
address_o = axi_req_i.ar.addr;
|
||||
// save the transaction id for reflection
|
||||
trans_id_n = slave.ar_id;
|
||||
trans_id_n = axi_req_i.ar.id;
|
||||
|
||||
end
|
||||
end
|
||||
|
@ -101,22 +102,22 @@ module axi_lite_interface #(
|
|||
// enable the ram-like
|
||||
en_o = 1'b1;
|
||||
// we are not ready for another request here
|
||||
slave.ar_ready = 1'b0;
|
||||
axi_resp_o.ar_ready = 1'b0;
|
||||
// further assert the correct address
|
||||
address_o = address_q;
|
||||
// the read is valid
|
||||
slave.r_valid = 1'b1;
|
||||
axi_resp_o.r_valid = 1'b1;
|
||||
// check if we got a valid r_ready and go back to IDLE
|
||||
if (slave.r_ready)
|
||||
if (axi_req_i.r_ready)
|
||||
NS = IDLE;
|
||||
end
|
||||
// We've got a write request at least one cycle earlier
|
||||
// wait here for the data
|
||||
WRITE: begin
|
||||
if (slave.w_valid) begin
|
||||
if (axi_req_i.w_valid) begin
|
||||
// we are not ready for another request here
|
||||
slave.ar_ready = 1'b0;
|
||||
slave.w_ready = 1'b1;
|
||||
axi_resp_o.ar_ready = 1'b0;
|
||||
axi_resp_o.w_ready = 1'b1;
|
||||
// use the latched address
|
||||
address_o = address_q;
|
||||
en_o = 1'b1;
|
||||
|
@ -127,9 +128,9 @@ module axi_lite_interface #(
|
|||
end
|
||||
|
||||
WRITE_B: begin
|
||||
slave.b_valid = 1'b1;
|
||||
axi_resp_o.b_valid = 1'b1;
|
||||
// we've already performed the write here so wait for the ready signal
|
||||
if (slave.b_ready)
|
||||
if (axi_req_i.b_ready)
|
||||
NS = IDLE;
|
||||
end
|
||||
default:;
|
||||
|
@ -159,10 +160,10 @@ module axi_lite_interface #(
|
|||
//pragma translate_off
|
||||
`ifndef VERILATOR
|
||||
// check that burst length is just one
|
||||
assert property (@(posedge clk_i) slave.ar_valid |-> ((slave.ar_len == 8'b0)))
|
||||
assert property (@(posedge clk_i) axi_req_i.ar_valid |-> ((axi_req_i.ar.len == 8'b0)))
|
||||
else begin $error("AXI Lite does not support bursts larger than 1 or byte length unequal to the native bus size"); $stop(); end
|
||||
// do the same for the write channel
|
||||
assert property (@(posedge clk_i) slave.aw_valid |-> ((slave.aw_len == 8'b0)))
|
||||
assert property (@(posedge clk_i) axi_req_i.aw_valid |-> ((axi_req_i.aw.len == 8'b0)))
|
||||
else begin $error("AXI Lite does not support bursts larger than 1 or byte length unequal to the native bus size"); $stop(); end
|
||||
`endif
|
||||
//pragma translate_on
|
||||
|
|
|
@ -25,8 +25,8 @@ module clint #(
|
|||
input logic clk_i, // Clock
|
||||
input logic rst_ni, // Asynchronous reset active low
|
||||
input logic testmode_i,
|
||||
AXI_BUS.Slave slave,
|
||||
|
||||
input ariane_axi::req_t axi_req_i,
|
||||
output ariane_axi::resp_t axi_resp_o,
|
||||
input logic rtc_i, // Real-time clock in (usually 32.768 kHz)
|
||||
output logic [NR_CORES-1:0] timer_irq_o, // Timer interrupts
|
||||
output logic [NR_CORES-1:0] ipi_o // software interrupt (a.k.a inter-process-interrupt)
|
||||
|
|
|
@ -32,10 +32,13 @@ module dm_top #(
|
|||
output logic [NrHarts-1:0] debug_req_o, // async debug request
|
||||
input logic [NrHarts-1:0] unavailable_i, // communicate whether the hart is unavailable (e.g.: power down)
|
||||
|
||||
AXI_BUS.Slave axi_slave, // bus slave, for an execution based technique
|
||||
// bus slave, for an execution based technique
|
||||
input ariane_axi::req_t axi_s_req_i,
|
||||
output ariane_axi::resp_t axi_s_resp_o,
|
||||
|
||||
// bus master, for system bus accesses
|
||||
output ariane_axi::req_t axi_req_o,
|
||||
input ariane_axi::resp_t axi_resp_i,
|
||||
output ariane_axi::req_t axi_m_req_o,
|
||||
input ariane_axi::resp_t axi_m_resp_i,
|
||||
|
||||
// Connection to DTM - compatible to RocketChip Debug Module
|
||||
input logic dmi_rst_ni,
|
||||
|
@ -148,8 +151,8 @@ module dm_top #(
|
|||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.dmactive_i ( dmactive_o ),
|
||||
.axi_req_o,
|
||||
.axi_resp_i,
|
||||
.axi_req_o ( axi_m_req_o ),
|
||||
.axi_resp_i ( axi_m_resp_i ),
|
||||
.sbaddress_i ( sbaddress_csrs_sba ),
|
||||
.sbaddress_o ( sbaddress_sba_csrs ),
|
||||
.sbaddress_write_valid_i ( sbaddress_write_valid ),
|
||||
|
@ -195,20 +198,33 @@ module dm_top #(
|
|||
.rdata_o ( rdata )
|
||||
);
|
||||
|
||||
AXI_BUS #(
|
||||
.AXI_ID_WIDTH ( AxiIdWidth ),
|
||||
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
|
||||
.AXI_DATA_WIDTH ( AxiDataWidth ),
|
||||
.AXI_USER_WIDTH ( AxiUserWidth )
|
||||
) slave();
|
||||
|
||||
axi_slave_connect_rev i_axi_slave_connect_rev (
|
||||
.axi_req_i (axi_s_req_i),
|
||||
.axi_resp_o(axi_s_resp_o),
|
||||
.slave(slave));
|
||||
|
||||
axi2mem #(
|
||||
.AXI_ID_WIDTH ( AxiIdWidth ),
|
||||
.AXI_ADDR_WIDTH ( AxiAddrWidth ),
|
||||
.AXI_DATA_WIDTH ( AxiDataWidth ),
|
||||
.AXI_USER_WIDTH ( AxiUserWidth )
|
||||
) i_axi2mem (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.slave ( axi_slave ),
|
||||
.req_o ( req ),
|
||||
.we_o ( we ),
|
||||
.addr_o ( addr ),
|
||||
.be_o ( be ),
|
||||
.data_o ( wdata ),
|
||||
.data_i ( rdata )
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.slave ( slave ),
|
||||
.req_o ( req ),
|
||||
.we_o ( we ),
|
||||
.addr_o ( addr ),
|
||||
.be_o ( be ),
|
||||
.data_o ( wdata ),
|
||||
.data_i ( rdata )
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Description: Connects SV AXI interface to structs used by Ariane
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
module axi_connect (
|
||||
input ariane_axi::req_t axi_req_i,
|
||||
output ariane_axi::resp_t axi_resp_o,
|
||||
AXI_BUS.out master
|
||||
);
|
||||
|
||||
assign master.aw_id = axi_req_i.aw.id;
|
||||
assign master.aw_addr = axi_req_i.aw.addr;
|
||||
assign master.aw_len = axi_req_i.aw.len;
|
||||
assign master.aw_size = axi_req_i.aw.size;
|
||||
assign master.aw_burst = axi_req_i.aw.burst;
|
||||
assign master.aw_lock = axi_req_i.aw.lock;
|
||||
assign master.aw_cache = axi_req_i.aw.cache;
|
||||
assign master.aw_prot = axi_req_i.aw.prot;
|
||||
assign master.aw_qos = axi_req_i.aw.qos;
|
||||
assign master.aw_region = axi_req_i.aw.region;
|
||||
assign master.aw_user = '0;
|
||||
assign master.aw_valid = axi_req_i.aw_valid;
|
||||
assign axi_resp_o.aw_ready = master.aw_ready;
|
||||
|
||||
assign master.w_data = axi_req_i.w.data;
|
||||
assign master.w_strb = axi_req_i.w.strb;
|
||||
assign master.w_last = axi_req_i.w.last;
|
||||
assign master.w_user = '0;
|
||||
assign master.w_valid = axi_req_i.w_valid;
|
||||
assign axi_resp_o.w_ready = master.w_ready;
|
||||
|
||||
assign axi_resp_o.b.id = master.b_id;
|
||||
assign axi_resp_o.b.resp = master.b_resp;
|
||||
assign axi_resp_o.b_valid = master.b_valid;
|
||||
assign master.b_ready = axi_req_i.b_ready;
|
||||
|
||||
assign master.ar_id = axi_req_i.ar.id;
|
||||
assign master.ar_addr = axi_req_i.ar.addr;
|
||||
assign master.ar_len = axi_req_i.ar.len;
|
||||
assign master.ar_size = axi_req_i.ar.size;
|
||||
assign master.ar_burst = axi_req_i.ar.burst;
|
||||
assign master.ar_lock = axi_req_i.ar.lock;
|
||||
assign master.ar_cache = axi_req_i.ar.cache;
|
||||
assign master.ar_prot = axi_req_i.ar.prot;
|
||||
assign master.ar_qos = axi_req_i.ar.qos;
|
||||
assign master.ar_region = axi_req_i.ar.region;
|
||||
assign master.ar_user = '0;
|
||||
assign master.ar_valid = axi_req_i.ar_valid;
|
||||
assign axi_resp_o.ar_ready = master.ar_ready;
|
||||
|
||||
assign axi_resp_o.r.id = master.r_id;
|
||||
assign axi_resp_o.r.data = master.r_data;
|
||||
assign axi_resp_o.r.resp = master.r_resp;
|
||||
assign axi_resp_o.r.last = master.r_last;
|
||||
assign axi_resp_o.r_valid = master.r_valid;
|
||||
assign master.r_ready = axi_req_i.r_ready;
|
||||
|
||||
endmodule
|
67
src/util/axi_master_connect.sv
Normal file
67
src/util/axi_master_connect.sv
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Description: Connects SV AXI interface to structs used by Ariane
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
module axi_master_connect (
|
||||
input ariane_axi::req_t axi_req_i,
|
||||
output ariane_axi::resp_t axi_resp_o,
|
||||
AXI_BUS.out master
|
||||
);
|
||||
|
||||
assign master.aw_id = axi_req_i.aw.id;
|
||||
assign master.aw_addr = axi_req_i.aw.addr;
|
||||
assign master.aw_len = axi_req_i.aw.len;
|
||||
assign master.aw_size = axi_req_i.aw.size;
|
||||
assign master.aw_burst = axi_req_i.aw.burst;
|
||||
assign master.aw_lock = axi_req_i.aw.lock;
|
||||
assign master.aw_cache = axi_req_i.aw.cache;
|
||||
assign master.aw_prot = axi_req_i.aw.prot;
|
||||
assign master.aw_qos = axi_req_i.aw.qos;
|
||||
assign master.aw_region = axi_req_i.aw.region;
|
||||
assign master.aw_user = '0;
|
||||
assign master.aw_valid = axi_req_i.aw_valid;
|
||||
assign axi_resp_o.aw_ready = master.aw_ready;
|
||||
|
||||
assign master.w_data = axi_req_i.w.data;
|
||||
assign master.w_strb = axi_req_i.w.strb;
|
||||
assign master.w_last = axi_req_i.w.last;
|
||||
assign master.w_user = '0;
|
||||
assign master.w_valid = axi_req_i.w_valid;
|
||||
assign axi_resp_o.w_ready = master.w_ready;
|
||||
|
||||
assign axi_resp_o.b.id = master.b_id;
|
||||
assign axi_resp_o.b.resp = master.b_resp;
|
||||
assign axi_resp_o.b_valid = master.b_valid;
|
||||
assign master.b_ready = axi_req_i.b_ready;
|
||||
|
||||
assign master.ar_id = axi_req_i.ar.id;
|
||||
assign master.ar_addr = axi_req_i.ar.addr;
|
||||
assign master.ar_len = axi_req_i.ar.len;
|
||||
assign master.ar_size = axi_req_i.ar.size;
|
||||
assign master.ar_burst = axi_req_i.ar.burst;
|
||||
assign master.ar_lock = axi_req_i.ar.lock;
|
||||
assign master.ar_cache = axi_req_i.ar.cache;
|
||||
assign master.ar_prot = axi_req_i.ar.prot;
|
||||
assign master.ar_qos = axi_req_i.ar.qos;
|
||||
assign master.ar_region = axi_req_i.ar.region;
|
||||
assign master.ar_user = '0;
|
||||
assign master.ar_valid = axi_req_i.ar_valid;
|
||||
assign axi_resp_o.ar_ready = master.ar_ready;
|
||||
|
||||
assign axi_resp_o.r.id = master.r_id;
|
||||
assign axi_resp_o.r.data = master.r_data;
|
||||
assign axi_resp_o.r.resp = master.r_resp;
|
||||
assign axi_resp_o.r.last = master.r_last;
|
||||
assign axi_resp_o.r_valid = master.r_valid;
|
||||
assign master.r_ready = axi_req_i.r_ready;
|
||||
|
||||
endmodule
|
67
src/util/axi_master_connect_rev.sv
Normal file
67
src/util/axi_master_connect_rev.sv
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Description: Connects SV AXI interface to structs used by Ariane
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
module axi_master_connect_rev (
|
||||
output ariane_axi::req_t axi_req_o,
|
||||
input ariane_axi::resp_t axi_resp_i,
|
||||
AXI_BUS.in master
|
||||
);
|
||||
|
||||
assign axi_req_o.aw.id = master.aw_id;
|
||||
assign axi_req_o.aw.addr = master.aw_addr;
|
||||
assign axi_req_o.aw.len = master.aw_len;
|
||||
assign axi_req_o.aw.size = master.aw_size;
|
||||
assign axi_req_o.aw.burst = master.aw_burst;
|
||||
assign axi_req_o.aw.lock = master.aw_lock;
|
||||
assign axi_req_o.aw.cache = master.aw_cache;
|
||||
assign axi_req_o.aw.prot = master.aw_prot;
|
||||
assign axi_req_o.aw.qos = master.aw_qos;
|
||||
assign axi_req_o.aw.region = master.aw_region;
|
||||
// assign = master.aw_user;
|
||||
assign axi_req_o.aw_valid = master.aw_valid;
|
||||
assign master.aw_ready = axi_resp_i.aw_ready;
|
||||
|
||||
assign axi_req_o.w.data = master.w_data;
|
||||
assign axi_req_o.w.strb = master.w_strb;
|
||||
assign axi_req_o.w.last = master.w_last;
|
||||
// assign = master.w_user;
|
||||
assign axi_req_o.w_valid = master.w_valid;
|
||||
assign master.w_ready = axi_resp_i.w_ready;
|
||||
|
||||
assign master.b_id = axi_resp_i.b.id;
|
||||
assign master.b_resp = axi_resp_i.b.resp;
|
||||
assign master.b_valid = axi_resp_i.b_valid;
|
||||
assign axi_req_o.b_ready = master.b_ready;
|
||||
|
||||
assign axi_req_o.ar.id = master.ar_id;
|
||||
assign axi_req_o.ar.addr = master.ar_addr;
|
||||
assign axi_req_o.ar.len = master.ar_len;
|
||||
assign axi_req_o.ar.size = master.ar_size;
|
||||
assign axi_req_o.ar.burst = master.ar_burst;
|
||||
assign axi_req_o.ar.lock = master.ar_lock;
|
||||
assign axi_req_o.ar.cache = master.ar_cache;
|
||||
assign axi_req_o.ar.prot = master.ar_prot;
|
||||
assign axi_req_o.ar.qos = master.ar_qos;
|
||||
assign axi_req_o.ar.region = master.ar_region;
|
||||
// assign = master.ar_user;
|
||||
assign axi_req_o.ar_valid = master.ar_valid;
|
||||
assign master.ar_ready = axi_resp_i.ar_ready;
|
||||
|
||||
assign master.r_id = axi_resp_i.r.id;
|
||||
assign master.r_data = axi_resp_i.r.data;
|
||||
assign master.r_resp = axi_resp_i.r.resp;
|
||||
assign master.r_last = axi_resp_i.r.last;
|
||||
assign master.r_valid = axi_resp_i.r_valid;
|
||||
assign axi_req_o.r_ready = master.r_ready;
|
||||
|
||||
endmodule
|
67
src/util/axi_slave_connect.sv
Normal file
67
src/util/axi_slave_connect.sv
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Description: Connects SV AXI interface to structs used by Ariane
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
module axi_slave_connect (
|
||||
output ariane_axi::req_t axi_req_o,
|
||||
input ariane_axi::resp_t axi_resp_i,
|
||||
AXI_BUS.in slave
|
||||
);
|
||||
|
||||
assign axi_req_o.aw.id = slave.aw_id;
|
||||
assign axi_req_o.aw.addr = slave.aw_addr;
|
||||
assign axi_req_o.aw.len = slave.aw_len;
|
||||
assign axi_req_o.aw.size = slave.aw_size;
|
||||
assign axi_req_o.aw.burst = slave.aw_burst;
|
||||
assign axi_req_o.aw.lock = slave.aw_lock;
|
||||
assign axi_req_o.aw.cache = slave.aw_cache;
|
||||
assign axi_req_o.aw.prot = slave.aw_prot;
|
||||
assign axi_req_o.aw.qos = slave.aw_qos;
|
||||
assign axi_req_o.aw.region = slave.aw_region;
|
||||
// assign = slave.aw_user;
|
||||
assign axi_req_o.aw_valid = slave.aw_valid;
|
||||
assign slave.aw_ready = axi_resp_i.aw_ready;
|
||||
|
||||
assign axi_req_o.w.data = slave.w_data;
|
||||
assign axi_req_o.w.strb = slave.w_strb;
|
||||
assign axi_req_o.w.last = slave.w_last;
|
||||
// assign = slave.w_user;
|
||||
assign axi_req_o.w_valid = slave.w_valid;
|
||||
assign slave.w_ready = axi_resp_i.w_ready;
|
||||
|
||||
assign slave.b_id = axi_resp_i.b.id;
|
||||
assign slave.b_resp = axi_resp_i.b.resp;
|
||||
assign slave.b_valid = axi_resp_i.b_valid;
|
||||
assign axi_req_o.b_ready = slave.b_ready;
|
||||
|
||||
assign axi_req_o.ar.id = slave.ar_id;
|
||||
assign axi_req_o.ar.addr = slave.ar_addr;
|
||||
assign axi_req_o.ar.len = slave.ar_len;
|
||||
assign axi_req_o.ar.size = slave.ar_size;
|
||||
assign axi_req_o.ar.burst = slave.ar_burst;
|
||||
assign axi_req_o.ar.lock = slave.ar_lock;
|
||||
assign axi_req_o.ar.cache = slave.ar_cache;
|
||||
assign axi_req_o.ar.prot = slave.ar_prot;
|
||||
assign axi_req_o.ar.qos = slave.ar_qos;
|
||||
assign axi_req_o.ar.region = slave.ar_region;
|
||||
// assign = slave.ar_user;
|
||||
assign axi_req_o.ar_valid = slave.ar_valid;
|
||||
assign slave.ar_ready = axi_resp_i.ar_ready;
|
||||
|
||||
assign slave.r_id = axi_resp_i.r.id;
|
||||
assign slave.r_data = axi_resp_i.r.data;
|
||||
assign slave.r_resp = axi_resp_i.r.resp;
|
||||
assign slave.r_last = axi_resp_i.r.last;
|
||||
assign slave.r_valid = axi_resp_i.r_valid;
|
||||
assign axi_req_o.r_ready = slave.r_ready;
|
||||
|
||||
endmodule
|
67
src/util/axi_slave_connect_rev.sv
Normal file
67
src/util/axi_slave_connect_rev.sv
Normal file
|
@ -0,0 +1,67 @@
|
|||
// Copyright 2018 ETH Zurich and University of Bologna.
|
||||
// Copyright and related rights are licensed under the Solderpad Hardware
|
||||
// License, Version 0.51 (the "License"); you may not use this file except in
|
||||
// compliance with the License. You may obtain a copy of the License at
|
||||
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
|
||||
// or agreed to in writing, software, hardware and materials distributed under
|
||||
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
//
|
||||
// Description: Connects SV AXI interface to structs used by Ariane
|
||||
// Author: Florian Zaruba <zarubaf@iis.ee.ethz.ch>
|
||||
|
||||
module axi_slave_connect_rev (
|
||||
input ariane_axi::req_t axi_req_i,
|
||||
output ariane_axi::resp_t axi_resp_o,
|
||||
AXI_BUS.out slave
|
||||
);
|
||||
|
||||
assign slave.aw_id = axi_req_i.aw.id;
|
||||
assign slave.aw_addr = axi_req_i.aw.addr;
|
||||
assign slave.aw_len = axi_req_i.aw.len;
|
||||
assign slave.aw_size = axi_req_i.aw.size;
|
||||
assign slave.aw_burst = axi_req_i.aw.burst;
|
||||
assign slave.aw_lock = axi_req_i.aw.lock;
|
||||
assign slave.aw_cache = axi_req_i.aw.cache;
|
||||
assign slave.aw_prot = axi_req_i.aw.prot;
|
||||
assign slave.aw_qos = axi_req_i.aw.qos;
|
||||
assign slave.aw_region = axi_req_i.aw.region;
|
||||
assign slave.aw_user = '0;
|
||||
assign slave.aw_valid = axi_req_i.aw_valid;
|
||||
assign axi_resp_o.aw_ready = slave.aw_ready;
|
||||
|
||||
assign slave.w_data = axi_req_i.w.data;
|
||||
assign slave.w_strb = axi_req_i.w.strb;
|
||||
assign slave.w_last = axi_req_i.w.last;
|
||||
assign slave.w_user = '0;
|
||||
assign slave.w_valid = axi_req_i.w_valid;
|
||||
assign axi_resp_o.w_ready = slave.w_ready;
|
||||
|
||||
assign axi_resp_o.b.id = slave.b_id;
|
||||
assign axi_resp_o.b.resp = slave.b_resp;
|
||||
assign axi_resp_o.b_valid = slave.b_valid;
|
||||
assign slave.b_ready = axi_req_i.b_ready;
|
||||
|
||||
assign slave.ar_id = axi_req_i.ar.id;
|
||||
assign slave.ar_addr = axi_req_i.ar.addr;
|
||||
assign slave.ar_len = axi_req_i.ar.len;
|
||||
assign slave.ar_size = axi_req_i.ar.size;
|
||||
assign slave.ar_burst = axi_req_i.ar.burst;
|
||||
assign slave.ar_lock = axi_req_i.ar.lock;
|
||||
assign slave.ar_cache = axi_req_i.ar.cache;
|
||||
assign slave.ar_prot = axi_req_i.ar.prot;
|
||||
assign slave.ar_qos = axi_req_i.ar.qos;
|
||||
assign slave.ar_region = axi_req_i.ar.region;
|
||||
assign slave.ar_user = '0;
|
||||
assign slave.ar_valid = axi_req_i.ar_valid;
|
||||
assign axi_resp_o.ar_ready = slave.ar_ready;
|
||||
|
||||
assign axi_resp_o.r.id = slave.r_id;
|
||||
assign axi_resp_o.r.data = slave.r_data;
|
||||
assign axi_resp_o.r.resp = slave.r_resp;
|
||||
assign axi_resp_o.r.last = slave.r_last;
|
||||
assign axi_resp_o.r_valid = slave.r_valid;
|
||||
assign slave.r_ready = axi_req_i.r_ready;
|
||||
|
||||
endmodule
|
|
@ -166,8 +166,8 @@ module ariane_testharness #(
|
|||
.exit ( dmi_exit )
|
||||
);
|
||||
|
||||
ariane_axi::req_t axi_sba_req;
|
||||
ariane_axi::resp_t axi_sba_resp;
|
||||
ariane_axi::req_t dm_axi_m_req, dm_axi_s_req;
|
||||
ariane_axi::resp_t dm_axi_m_resp, dm_axi_s_resp;
|
||||
|
||||
// debug module
|
||||
dm_top #(
|
||||
|
@ -185,9 +185,10 @@ module ariane_testharness #(
|
|||
.dmactive_o ( ), // active debug session
|
||||
.debug_req_o ( debug_req_core ),
|
||||
.unavailable_i ( '0 ),
|
||||
.axi_slave ( master[3] ),
|
||||
.axi_req_o ( axi_sba_req ),
|
||||
.axi_resp_i ( axi_sba_resp ),
|
||||
.axi_s_req_i ( dm_axi_s_req ),
|
||||
.axi_s_resp_o ( dm_axi_s_resp ),
|
||||
.axi_m_req_o ( dm_axi_m_req ),
|
||||
.axi_m_resp_i ( dm_axi_m_resp ),
|
||||
.dmi_rst_ni ( rst_ni ),
|
||||
.dmi_req_valid_i ( debug_req_valid ),
|
||||
.dmi_req_ready_o ( debug_req_ready ),
|
||||
|
@ -197,8 +198,8 @@ module ariane_testharness #(
|
|||
.dmi_resp_o ( debug_resp )
|
||||
);
|
||||
|
||||
axi_connect i_axi_connect_sba (.axi_req_i(axi_sba_req), .axi_resp_o(axi_sba_resp), .master(slave[1]));
|
||||
|
||||
axi_master_connect i_axi_master_dm (.axi_req_i(dm_axi_m_req), .axi_resp_o(dm_axi_m_resp), .master(slave[1]));
|
||||
axi_slave_connect i_axi_slave_dm (.axi_req_o(dm_axi_s_req), .axi_resp_i(dm_axi_s_resp), .slave(master[3]));
|
||||
|
||||
// ---------------
|
||||
// ROM
|
||||
|
@ -300,21 +301,27 @@ module ariane_testharness #(
|
|||
logic ipi;
|
||||
logic timer_irq;
|
||||
|
||||
ariane_axi::req_t axi_clint_req;
|
||||
ariane_axi::resp_t axi_clint_resp;
|
||||
|
||||
clint #(
|
||||
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
|
||||
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
|
||||
.AXI_ID_WIDTH ( AXI_ID_WIDTH_SLAVES ),
|
||||
.NR_CORES ( 1 )
|
||||
) i_clint (
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.testmode_i ( test_en ),
|
||||
.slave ( master[1] ),
|
||||
.rtc_i ( rtc_i ),
|
||||
.timer_irq_o ( timer_irq ),
|
||||
.ipi_o ( ipi )
|
||||
.clk_i ( clk_i ),
|
||||
.rst_ni ( rst_ni ),
|
||||
.testmode_i ( test_en ),
|
||||
.axi_req_i ( axi_clint_req ),
|
||||
.axi_resp_o ( axi_clint_resp ),
|
||||
.rtc_i ( rtc_i ),
|
||||
.timer_irq_o ( timer_irq ),
|
||||
.ipi_o ( ipi )
|
||||
);
|
||||
|
||||
axi_slave_connect i_axi_slave_connect_clint (.axi_req_o(axi_clint_req), .axi_resp_i(axi_clint_resp), .slave(master[1]));
|
||||
|
||||
// ---------------
|
||||
// Core
|
||||
// ---------------
|
||||
|
@ -336,7 +343,7 @@ module ariane_testharness #(
|
|||
.axi_resp_i ( axi_ariane_resp )
|
||||
);
|
||||
|
||||
axi_connect i_axi_connect_ariane (.axi_req_i(axi_ariane_req), .axi_resp_o(axi_ariane_resp), .master(slave[0]));
|
||||
axi_master_connect i_axi_master_connect_ariane (.axi_req_i(axi_ariane_req), .axi_resp_o(axi_ariane_resp), .master(slave[0]));
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue