Refactor readback mux implementation. Improves performance (#155) and eliminates illegal streaming operator usage (#165)
This commit is contained in:
0
tests/test_only_external_blocks/__init__.py
Normal file
0
tests/test_only_external_blocks/__init__.py
Normal file
11
tests/test_only_external_blocks/regblock.rdl
Normal file
11
tests/test_only_external_blocks/regblock.rdl
Normal file
@@ -0,0 +1,11 @@
|
||||
addrmap top {
|
||||
mem ext_mem #(
|
||||
longint SIZE = 0x100
|
||||
) {
|
||||
memwidth = 32;
|
||||
mementries = SIZE / 4;
|
||||
};
|
||||
|
||||
external ext_mem #(.SIZE(0x10)) mem1 @ 0x0000;
|
||||
external ext_mem #(.SIZE(0x90)) mem2 @ 0x0200;
|
||||
};
|
||||
115
tests/test_only_external_blocks/tb_template.sv
Normal file
115
tests/test_only_external_blocks/tb_template.sv
Normal file
@@ -0,0 +1,115 @@
|
||||
{% extends "lib/tb_base.sv" %}
|
||||
|
||||
|
||||
|
||||
{%- block dut_support %}
|
||||
{% sv_line_anchor %}
|
||||
|
||||
external_block #(
|
||||
.ADDR_WIDTH($clog2('h10))
|
||||
) mem1_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
.req(hwif_out.mem1.req),
|
||||
.req_is_wr(hwif_out.mem1.req_is_wr),
|
||||
.addr(hwif_out.mem1.addr),
|
||||
.wr_data(hwif_out.mem1.wr_data),
|
||||
.wr_biten(hwif_out.mem1.wr_biten),
|
||||
.rd_ack(hwif_in.mem1.rd_ack),
|
||||
.rd_data(hwif_in.mem1.rd_data),
|
||||
.wr_ack(hwif_in.mem1.wr_ack)
|
||||
);
|
||||
|
||||
external_block #(
|
||||
.ADDR_WIDTH($clog2('h90))
|
||||
) mem2_inst (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
.req(hwif_out.mem2.req),
|
||||
.req_is_wr(hwif_out.mem2.req_is_wr),
|
||||
.addr(hwif_out.mem2.addr),
|
||||
.wr_data(hwif_out.mem2.wr_data),
|
||||
.wr_biten(hwif_out.mem2.wr_biten),
|
||||
.rd_ack(hwif_in.mem2.rd_ack),
|
||||
.rd_data(hwif_in.mem2.rd_data),
|
||||
.wr_ack(hwif_in.mem2.wr_ack)
|
||||
);
|
||||
|
||||
{%- endblock %}
|
||||
|
||||
|
||||
|
||||
{% block seq %}
|
||||
{% sv_line_anchor %}
|
||||
##1;
|
||||
cb.rst <= '0;
|
||||
##1;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Simple read/write tests
|
||||
//--------------------------------------------------------------------------
|
||||
// mem1
|
||||
repeat(32) begin
|
||||
logic [31:0] x;
|
||||
int unsigned addr;
|
||||
x = $urandom();
|
||||
addr = 'h0;
|
||||
addr += $urandom_range(('h10 / 4) - 1) * 4;
|
||||
cpuif.write(addr, x);
|
||||
cpuif.assert_read(addr, x);
|
||||
end
|
||||
|
||||
// mem2
|
||||
repeat(32) begin
|
||||
logic [31:0] x;
|
||||
int unsigned addr;
|
||||
x = $urandom();
|
||||
addr = 'h200;
|
||||
addr += $urandom_range(('h90 / 4) - 1) * 4;
|
||||
cpuif.write(addr, x);
|
||||
cpuif.assert_read(addr, x);
|
||||
end
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Pipelined access
|
||||
//--------------------------------------------------------------------------
|
||||
// init array with unique known value
|
||||
for(int i=0; i<('h10 / 4); i++) begin
|
||||
cpuif.write('h0 + i*4, 'h1000 + i);
|
||||
end
|
||||
for(int i=0; i<('h90 / 4); i++) begin
|
||||
cpuif.write('h200 + i*4, 'h3000 + i);
|
||||
end
|
||||
|
||||
// random pipelined read/writes
|
||||
repeat(256) begin
|
||||
fork
|
||||
begin
|
||||
int i;
|
||||
logic [31:0] x;
|
||||
int unsigned addr;
|
||||
case($urandom_range(1))
|
||||
0: begin
|
||||
i = $urandom_range(('h10 / 4) - 1);
|
||||
x = 'h1000 + i;
|
||||
addr = 'h0 + i*4;
|
||||
end
|
||||
1: begin
|
||||
i = $urandom_range(('h90 / 4) - 1);
|
||||
x = 'h3000 + i;
|
||||
addr = 'h200 + i*4;
|
||||
end
|
||||
endcase
|
||||
|
||||
case($urandom_range(1))
|
||||
0: cpuif.write(addr, x);
|
||||
1: cpuif.assert_read(addr, x);
|
||||
endcase
|
||||
end
|
||||
join_none
|
||||
end
|
||||
wait fork;
|
||||
|
||||
{% endblock %}
|
||||
29
tests/test_only_external_blocks/testcase.py
Normal file
29
tests/test_only_external_blocks/testcase.py
Normal file
@@ -0,0 +1,29 @@
|
||||
from parameterized import parameterized_class
|
||||
|
||||
from ..lib.cpuifs.apb4 import APB4
|
||||
from ..lib.cpuifs.axi4lite import AXI4Lite
|
||||
from ..lib.cpuifs.passthrough import Passthrough
|
||||
from ..lib.sim_testcase import SimTestCase
|
||||
from ..lib.test_params import get_permutation_class_name, get_permutations
|
||||
|
||||
|
||||
@parameterized_class(get_permutations({
|
||||
"cpuif": [
|
||||
APB4(),
|
||||
Passthrough(),
|
||||
],
|
||||
"retime_read_fanin": [True, False],
|
||||
"retime_read_response": [True, False],
|
||||
"retime_external": [True, False],
|
||||
}), class_name_func=get_permutation_class_name)
|
||||
class Test(SimTestCase):
|
||||
extra_tb_files = [
|
||||
"../lib/external_reg.sv",
|
||||
"../lib/external_block.sv",
|
||||
]
|
||||
init_hwif_in = False
|
||||
clocking_hwif_in = False
|
||||
timeout_clk_cycles = 30000
|
||||
|
||||
def test_dut(self):
|
||||
self.run_test()
|
||||
Reference in New Issue
Block a user