Skip to content

Commit

Permalink
axi_dwc_downsizer: Add testbench for the DW Downsizer
Browse files Browse the repository at this point in the history
  • Loading branch information
suehtamacv committed Mar 23, 2020
1 parent 7b8dc23 commit adce885
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 49 deletions.
1 change: 1 addition & 0 deletions Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ sources:
- test/tb_axi_atop_filter.sv
- test/tb_axi_cdc.sv
- test/tb_axi_delayer.sv
- test/tb_axi_dw_downsizer.sv
- test/tb_axi_isolate.sv
- test/tb_axi_lite_to_apb.sv
- test/tb_axi_lite_to_axi.sv
Expand Down
6 changes: 6 additions & 0 deletions scripts/run_vsim.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ for DW in 8 16 32 64 128 256 512 1024; do
call_vsim tb_axi_lite_to_axi -GDW=$DW -t 1ps -c
done

for DW in 8 16 32 64 128 256 512 1024; do
for (( MULT = 2; MULT <= `echo 1024/$DW`; MULT *= 2 )); do
call_vsim tb_axi_dw_downsizer -GDW=$DW -GMULT=$MULT -t 1ps -c
done
done

call_vsim tb_axi_delayer
for MAX_TXNS in 1 3 12; do
call_vsim tb_axi_atop_filter -GN_TXNS=1000 -GAXI_MAX_WRITE_TXNS=$MAX_TXNS
Expand Down
4 changes: 2 additions & 2 deletions src/axi_dw_converter.sv
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ module axi_dw_converter #(
.AxiMaxTrans (AxiMaxTrans ),
.AxiIdWidth (AxiIdWidth ),
.AxiUserWidth (AxiUserWidth )
) i_axi_data_upsize (
) i_axi_dw_upsizer (
.clk_i (clk_i ),
.rst_ni (rst_ni ),
.slv_aw_id (slv.aw_id ),
Expand Down Expand Up @@ -160,7 +160,7 @@ module axi_dw_converter #(
.AxiMaxTrans (AxiMaxTrans ),
.AxiIdWidth (AxiIdWidth ),
.AxiUserWidth (AxiUserWidth )
) i_axi_data_downsize (
) i_axi_dw_downsizer (
.clk_i (clk_i ),
.rst_ni (rst_ni ),
.slv_aw_id (slv.aw_id ),
Expand Down
54 changes: 27 additions & 27 deletions src/axi_dw_downsizer.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
// Data width downsize conversion.
// Connects a narrow master to a wider slave.

`include "axi/typedef.svh"

import axi_pkg::*;

module axi_dw_downsizer #(
parameter int AxiAddrWidth = 64 ,
parameter int AxiMstDataWidth = 64 ,
parameter int AxiSlvDataWidth = 64 ,
parameter int AxiMaxTrans = 1 ,
parameter int AxiIdWidth = 4 ,
parameter int AxiUserWidth = 1 ,
parameter int AxiAddrWidth = 64,
parameter int AxiMstDataWidth = 64,
parameter int AxiSlvDataWidth = 64,
parameter int AxiMaxTrans = 1 ,
parameter int AxiIdWidth = 4 ,
parameter int AxiUserWidth = 1 ,

// Dependent parameters, do not change!
parameter AxiMstStrbWidth = AxiMstDataWidth/8 ,
Expand Down Expand Up @@ -174,7 +176,7 @@ module axi_dw_downsizer #(
.AxiVldRdy(1'b1 ),
.ExtPrio (1'b0 ),
.LockIn (1'b1 )
) i_arbiter_slv_r (
) i_slv_r_arb (
.clk_i (clk_i ),
.rst_ni (rst_ni ),
.flush_i(1'b0 ),
Expand Down Expand Up @@ -216,8 +218,7 @@ module axi_dw_downsizer #(
qos : slv_ar_qos ,
region: slv_ar_region,
atop : '0 ,
user : slv_ar_user ,
valid : slv_ar_valid
user : slv_ar_user
};
assign slv_aw = '{
id : slv_aw_id ,
Expand All @@ -231,8 +232,7 @@ module axi_dw_downsizer #(
qos : slv_aw_qos ,
region: slv_aw_region,
atop : slv_aw_atop ,
user : slv_aw_user ,
valid : slv_aw_valid
user : slv_aw_user
};

rr_arb_tree #(
Expand Down Expand Up @@ -278,7 +278,7 @@ module axi_dw_downsizer #(
.AxiVldRdy(1'b1 ),
.ExtPrio (1'b0 ),
.LockIn (1'b1 )
) i_arbiter_mst_ar (
) i_mst_ar_arb (
.clk_i (clk_i ),
.rst_ni (rst_ni ),
.flush_i(1'b0 ),
Expand Down Expand Up @@ -462,7 +462,7 @@ module axi_dw_downsizer #(
r_req_d.ar.len = 255 - align_adj ;
end
end
end : BURST_INCR
end
endcase
end
end
Expand All @@ -481,16 +481,16 @@ module axi_dw_downsizer #(
mst_r_ready_tran[t] = 1'b1;

if (mst_r_valid) begin
automatic addr_t mi_offset = r_req_q.ar.addr[$clog2(AxiMstStrbWidth)-1:0] ;
automatic addr_t si_offset = r_req_q.ar.addr[$clog2(AxiSlvStrbWidth)-1:0] ;
automatic addr_t size_mask = (1 << r_req_q.ar.size) - 1 ;
automatic addr_t mst_offset = r_req_q.ar.addr[(AxiMstStrbWidth == 1 ? 1 : $clog2(AxiMstStrbWidth)) - 1:0];
automatic addr_t slv_offset = r_req_q.ar.addr[(AxiSlvStrbWidth == 1 ? 1 : $clog2(AxiSlvStrbWidth)) - 1:0];
automatic addr_t size_mask = (1 << r_req_q.ar.size) - 1 ;

// Lane steering
for (int b = 0; b < AxiSlvStrbWidth; b++) begin
if ((b >= si_offset) &&
(b - si_offset < (1 << r_req_q.size)) &&
(b + mi_offset - si_offset < AxiMstStrbWidth)) begin
r_req_d.r.data[8*b+:8] = mst_r_data[8 * (b + mi_offset - si_offset) +: 8];
if ((b >= slv_offset) &&
(b - slv_offset < (1 << r_req_q.size)) &&
(b + mst_offset - slv_offset < AxiMstStrbWidth)) begin
r_req_d.r.data[8*b+:8] = mst_r_data[8 * (b + mst_offset - slv_offset) +: 8];
end
end

Expand Down Expand Up @@ -610,8 +610,8 @@ module axi_dw_downsizer #(
// Request was accepted
if (!w_req_q.aw_valid)
if (slv_w_valid) begin
automatic addr_t mi_offset = w_req_q.aw.addr[$clog2(AxiMstStrbWidth)-1:0] ;
automatic addr_t si_offset = w_req_q.aw.addr[$clog2(AxiSlvStrbWidth)-1:0] ;
automatic addr_t mst_offset = w_req_q.aw.addr[(AxiMstStrbWidth == 1 ? 1 : $clog2(AxiMstStrbWidth)) - 1:0];
automatic addr_t slv_offset = w_req_q.aw.addr[(AxiSlvStrbWidth == 1 ? 1 : $clog2(AxiSlvStrbWidth)) - 1:0];

// Valid output
mst_w_valid = 1'b1 ;
Expand All @@ -620,11 +620,11 @@ module axi_dw_downsizer #(

// Serialization
for (int b = 0; b < AxiSlvStrbWidth; b++)
if ((b >= si_offset) &&
(b - si_offset < (1 << w_req_q.aw.size)) &&
(b + mi_offset - si_offset < AxiMstStrbWidth)) begin
mst_w_data[8 * (b + mi_offset - si_offset) +: 8] = slv_w_data[8 * b +: 8];
mst_w_strb[b + mi_offset - si_offset] = slv_w_strb[b] ;
if ((b >= slv_offset) &&
(b - slv_offset < (1 << w_req_q.aw.size)) &&
(b + mst_offset - slv_offset < AxiMstStrbWidth)) begin
mst_w_data[8 * (b + mst_offset - slv_offset) +: 8] = slv_w_data[8 * b +: 8];
mst_w_strb[b + mst_offset - slv_offset] = slv_w_strb[b] ;
end
end

Expand Down
40 changes: 20 additions & 20 deletions src/axi_dw_upsizer.sv
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
// Data width upsize conversion.
// Connects a wide master to a narrower slave.

`include "axi/typedef.svh"

import axi_pkg::*;

module axi_dw_upsizer #(
Expand Down Expand Up @@ -168,7 +170,7 @@ module axi_dw_upsizer #(
.DataType (slv_r_chan_t),
.ExtPrio (1'b0 ),
.AxiVldRdy(1'b1 )
) i_arbiter_slv_r (
) i_slv_r_arb (
.clk_i (clk_i ),
.rst_ni (rst_ni ),
.flush_i(1'b0 ),
Expand Down Expand Up @@ -210,8 +212,7 @@ module axi_dw_upsizer #(
qos : slv_ar_qos ,
region: slv_ar_region,
atop : '0 ,
user : slv_ar_user ,
valid : slv_ar_valid
user : slv_ar_user
};
assign slv_aw = '{
id : slv_aw_id ,
Expand All @@ -225,8 +226,7 @@ module axi_dw_upsizer #(
qos : slv_aw_qos ,
region: slv_aw_region,
atop : slv_aw_atop ,
user : slv_aw_user ,
valid : slv_aw_valid
user : slv_aw_user
};

rr_arb_tree #(
Expand Down Expand Up @@ -272,7 +272,7 @@ module axi_dw_upsizer #(
.AxiVldRdy(1'b1 ),
.ExtPrio (1'b0 ),
.LockIn (1'b1 )
) i_arbiter_mst_ar (
) i_mst_ar_arb (
.clk_i (clk_i ),
.rst_ni (rst_ni ),
.flush_i(1'b0 ),
Expand Down Expand Up @@ -449,19 +449,19 @@ module axi_dw_upsizer #(
// Request was accepted
if (!r_req_q.ar_valid)
if (mst_r_valid && (idqueue_id == t) && idqueue_valid) begin
automatic addr_t mi_offset = r_req_q.ar.addr[$clog2(AxiMstStrbWidth)-1:0];
automatic addr_t si_offset = r_req_q.ar.addr[$clog2(AxiSlvStrbWidth)-1:0];
automatic addr_t mst_offset = r_req_q.ar.addr[(AxiMstStrbWidth == 1 ? 1 : $clog2(AxiMstStrbWidth)) - 1:0];
automatic addr_t slv_offset = r_req_q.ar.addr[(AxiSlvStrbWidth == 1 ? 1 : $clog2(AxiSlvStrbWidth)) - 1:0];

// Valid output
slv_r_valid_tran[t] = 1'b1 ;
slv_r_tran[t].last = mst_r_last && (r_req_q.len == 0);

// Serialization
for (int b = 0; b < AxiMstStrbWidth; b++)
if ((b >= mi_offset) &&
(b - mi_offset < (1 << r_req_q.size)) &&
(b + si_offset - mi_offset < AxiSlvStrbWidth)) begin
slv_r_tran[t].data[8*(b + si_offset - mi_offset) +: 8] = mst_r_data[8 * b +: 8];
if ((b >= mst_offset) &&
(b - mst_offset < (1 << r_req_q.size)) &&
(b + slv_offset - mst_offset < AxiSlvStrbWidth)) begin
slv_r_tran[t].data[8*(b + slv_offset - mst_offset) +: 8] = mst_r_data[8 * b +: 8];
end

// Acknowledgment
Expand Down Expand Up @@ -576,17 +576,17 @@ module axi_dw_upsizer #(
slv_w_ready = ~mst_w_valid || mst_w_ready;

if (slv_w_valid && slv_w_ready) begin
automatic addr_t mi_offset = w_req_q.aw.addr[$clog2(AxiMstStrbWidth)-1:0];
automatic addr_t si_offset = w_req_q.aw.addr[$clog2(AxiSlvStrbWidth)-1:0];
automatic addr_t size_mask = (1 << w_req_q.size) - 1 ;
automatic addr_t mst_offset = w_req_q.aw.addr[(AxiMstStrbWidth == 1 ? 1 : $clog2(AxiMstStrbWidth)) - 1:0];
automatic addr_t slv_offset = w_req_q.aw.addr[(AxiSlvStrbWidth == 1 ? 1 : $clog2(AxiSlvStrbWidth)) - 1:0];
automatic addr_t size_mask = (1 << w_req_q.size) - 1 ;

// Lane steering
for (int b = 0; b < AxiMstStrbWidth; b++)
if ((b >= mi_offset) &&
(b - mi_offset < (1 << w_req_q.size)) &&
(b + si_offset - mi_offset < AxiSlvStrbWidth)) begin
w_req_d.w.data[8 * b +: 8] = slv_w_data[8 * (b + si_offset - mi_offset) +: 8];
w_req_d.w.strb[b] = slv_w_strb[b + si_offset - mi_offset] ;
if ((b >= mst_offset) &&
(b - mst_offset < (1 << w_req_q.size)) &&
(b + slv_offset - mst_offset < AxiSlvStrbWidth)) begin
w_req_d.w.data[8 * b +: 8] = slv_w_data[8 * (b + slv_offset - mst_offset) +: 8];
w_req_d.w.strb[b] = slv_w_strb[b + slv_offset - mst_offset] ;
end

w_req_d.len = w_req_q.len - 1 ;
Expand Down
4 changes: 4 additions & 0 deletions test/tb_axi_dw_downsizer.do
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
add wave -position insertpoint \
sim:/tb_axi_dw_downsizer/i_dw_converter/gen_dw_downsize/i_axi_dw_downsizer/AxiMstDataWidth \
sim:/tb_axi_dw_downsizer/i_dw_converter/gen_dw_downsize/i_axi_dw_downsizer/AxiSlvDataWidth \
sim:/tb_axi_dw_downsizer/i_dw_converter/gen_dw_downsize/i_axi_dw_downsizer/*
125 changes: 125 additions & 0 deletions test/tb_axi_dw_downsizer.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright 2020 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

// File : tb_axi_dw_downsizer.sv
// Author : Matheus Cavalcante <[email protected]>
// Created : 09.02.2019

// Copyright (C) 2020 ETH Zurich, University of Bologna
// All rights reserved.

`include "axi/assign.svh"

module tb_axi_dw_downsizer;

parameter AW = 64;
parameter IW = 4;
parameter DW = 32;
parameter UW = 8;
parameter MULT = 8;

localparam tCK = 1ns;

logic clk = 0;
logic rst = 1;
logic done = 0;

AXI_BUS_DV #(
.AXI_ADDR_WIDTH (AW ),
.AXI_DATA_WIDTH (MULT * DW),
.AXI_ID_WIDTH (IW ),
.AXI_USER_WIDTH (UW )
) axi_master_dv (clk);

AXI_BUS #(
.AXI_ADDR_WIDTH (AW ),
.AXI_DATA_WIDTH (MULT * DW),
.AXI_ID_WIDTH (IW ),
.AXI_USER_WIDTH (UW )
) axi_master();

axi_test::rand_axi_master #(
.AW (AW ),
.DW (MULT * DW),
.IW (IW ),
.UW (UW ),
.MAX_READ_TXNS (8 ),
.MAX_WRITE_TXNS (8 ),
.TA (200ps ),
.TT (700ps )
) axi_master_drv = new ( axi_master_dv );

AXI_BUS_DV #(
.AXI_ADDR_WIDTH (AW),
.AXI_DATA_WIDTH (DW),
.AXI_ID_WIDTH (IW),
.AXI_USER_WIDTH (UW)
) axi_slave_dv (clk);

AXI_BUS #(
.AXI_ADDR_WIDTH (AW),
.AXI_DATA_WIDTH (DW),
.AXI_ID_WIDTH (IW),
.AXI_USER_WIDTH (UW)
) axi_slave ();

axi_test::rand_axi_slave #(
.AW (AW ),
.DW (DW ),
.IW (IW ),
.UW (UW ),
.TA (200ps),
.TT (700ps)
) axi_slave_drv = new (axi_slave_dv);

`AXI_ASSIGN(axi_master, axi_master_dv);
`AXI_ASSIGN(axi_slave_dv, axi_slave) ;

axi_dw_converter #(
.AxiSlvDataWidth(MULT*DW),
.AxiMstDataWidth(DW ),
.AxiIdWidth (IW ),
.AxiUserWidth (UW ),
.AxiMaxTrans (4 )
) i_dw_converter (
.clk_i (clk ),
.rst_ni(rst ),
.slv (axi_master),
.mst (axi_slave )
);

initial begin
#tCK;
rst <= 0;
#tCK;
rst <= 1;
#tCK;
while (!done) begin
clk <= 1;
#(tCK/2);
clk <= 0;
#(tCK/2);
end
end

initial begin
axi_master_drv.reset() ;
axi_master_drv.add_memory_region({AW{1'b0}}, {AW{1'b1}}, axi_pkg::WTHRU_NOALLOCATE);
axi_master_drv.run(50, 50) ;
done = 1;
end

initial begin
axi_slave_drv.reset();
axi_slave_drv.run() ;
end

// vsim -voptargs=+acc work.tb_axi_dw_downsizer
endmodule : tb_axi_dw_downsizer

0 comments on commit adce885

Please sign in to comment.