mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-06 17:44:09 +00:00
QLF_TDP36K: more basic tdp/sdp sim tests
Adds TDP submodule to generator. Adds shorthand expected signal to testbench (mostly to make it easier when I look at the vcd dump to figure out what I did wrong in tests).
This commit is contained in:
parent
3d08ed216d
commit
7f12d0ba95
|
@ -132,6 +132,26 @@ sync_ram_sdp #(\\
|
||||||
);\
|
);\
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
sync_ram_tdp_submodule = """\
|
||||||
|
sync_ram_tdp #(\\
|
||||||
|
.ADDRESS_WIDTH(ADDRESS_WIDTH),\\
|
||||||
|
.DATA_WIDTH(DATA_WIDTH)\\
|
||||||
|
) uut (\\
|
||||||
|
.clk_a(clk),\\
|
||||||
|
.clk_b(clk),\\
|
||||||
|
.write_enable_a(wce_a),\\
|
||||||
|
.write_enable_b(wce_b),\\
|
||||||
|
.read_enable_a(rce_a),\\
|
||||||
|
.read_enable_b(rce_b),\\
|
||||||
|
.addr_a(ra_a),\\
|
||||||
|
.addr_b(ra_b),\\
|
||||||
|
.read_data_a(rq_a),\\
|
||||||
|
.read_data_b(rq_b),\\
|
||||||
|
.write_data_a(wd_a),\\
|
||||||
|
.write_data_b(wd_b)\\
|
||||||
|
);\
|
||||||
|
"""
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class TestClass:
|
class TestClass:
|
||||||
params: dict[str, int]
|
params: dict[str, int]
|
||||||
|
@ -155,20 +175,81 @@ test_val_map = {
|
||||||
}
|
}
|
||||||
|
|
||||||
sim_tests: list[TestClass] = [
|
sim_tests: list[TestClass] = [
|
||||||
TestClass(
|
TestClass( # basic SDP test
|
||||||
|
# note that the common SDP model reads every cycle, but the testbench
|
||||||
|
# still uses the rce signal to check read assertions
|
||||||
params={"ADDRESS_WIDTH": 10, "DATA_WIDTH": 36},
|
params={"ADDRESS_WIDTH": 10, "DATA_WIDTH": 36},
|
||||||
top="sync_ram_sdp",
|
top="sync_ram_sdp",
|
||||||
assertions=["-assert-count 1 t:TDP36K"],
|
assertions=[],
|
||||||
test_steps=[
|
test_steps=[
|
||||||
{"wce_a": 1, "wa_a": 0x0A, "wd_a": 0xdeadbeef},
|
{"wce_a": 1, "wa_a": 0x0A, "wd_a": 0xdeadbeef},
|
||||||
{"wce_a": 1, "wa_a": 0xBA, "wd_a": 0x5a5a5a5a},
|
{"wce_a": 1, "wa_a": 0xBA, "wd_a": 0x5a5a5a5a},
|
||||||
{"wce_a": 1, "wa_a": 0xFF, "wd_a": 0},
|
{"wce_a": 1, "wa_a": 0xFF, "wd_a": 0},
|
||||||
{"rce_a": 1, "ra_a": 0xA},
|
{"rce_a": 1, "ra_a": 0x0A},
|
||||||
{"rq_a": 0xdeadbeef},
|
{"rq_a": 0xdeadbeef},
|
||||||
{"rce_a": 1, "ra_a": 0xFF},
|
{"rce_a": 1, "ra_a": 0xFF},
|
||||||
{"rq_a": 0},
|
{"rq_a": 0},
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
TestClass( # SDP read before write
|
||||||
|
params={"ADDRESS_WIDTH": 4, "DATA_WIDTH": 16},
|
||||||
|
top="sync_ram_sdp",
|
||||||
|
assertions=[],
|
||||||
|
test_steps=[
|
||||||
|
{"wce_a": 1, "wa_a": 0xA, "wd_a": 0x1234},
|
||||||
|
{"wce_a": 1, "wa_a": 0xA, "wd_a": 0x5678, "rce_a": 1, "ra_a": 0xA},
|
||||||
|
{"rq_a": 0x1234, "rce_a": 1, "ra_a": 0xA},
|
||||||
|
{"rq_a": 0x5678},
|
||||||
|
]
|
||||||
|
),
|
||||||
|
TestClass( # basic TDP test
|
||||||
|
# note that the testbench uses ra and wa, while the common TDP model
|
||||||
|
# uses a shared address
|
||||||
|
params={"ADDRESS_WIDTH": 10, "DATA_WIDTH": 36},
|
||||||
|
top="sync_ram_tdp",
|
||||||
|
assertions=[],
|
||||||
|
test_steps=[
|
||||||
|
{"wce_a": 1, "ra_a": 0x0A, "wce_b": 1, "ra_b": 0xBA,
|
||||||
|
"wd_a": 0xdeadbeef, "wd_b": 0x5a5a5a5a},
|
||||||
|
{"wce_a": 1, "ra_a": 0xFF,
|
||||||
|
"wd_a": 0},
|
||||||
|
{"rce_a": 1, "ra_a": 0x0A, "rce_b": 1, "ra_b": 0x0A},
|
||||||
|
{"rq_a": 0xdeadbeef, "rq_b": 0xdeadbeef},
|
||||||
|
{"rce_a": 1, "ra_a": 0xFF, "rce_b": 1, "ra_b": 0xBA},
|
||||||
|
{"rq_a": 0, "rq_b": 0x5a5a5a5a},
|
||||||
|
]
|
||||||
|
),
|
||||||
|
TestClass( # TDP with truncation
|
||||||
|
params={"ADDRESS_WIDTH": 4, "DATA_WIDTH": 16},
|
||||||
|
top="sync_ram_tdp",
|
||||||
|
assertions=[],
|
||||||
|
test_steps=[
|
||||||
|
{"wce_a": 1, "ra_a": 0x0F, "wce_b": 1, "ra_b": 0xBA,
|
||||||
|
"wd_a": 0xdeadbeef, "wd_b": 0x5a5a5a5a},
|
||||||
|
{"wce_a": 1, "ra_a": 0xFF,
|
||||||
|
"wd_a": 0},
|
||||||
|
{"rce_a": 1, "ra_a": 0x0F, "rce_b": 1, "ra_b": 0x0A},
|
||||||
|
{"rq_a": 0, "rq_b": 0x00005a5a},
|
||||||
|
]
|
||||||
|
),
|
||||||
|
TestClass( # TDP read before write
|
||||||
|
# note that the testbench uses rce and wce, while the common TDP model
|
||||||
|
# uses a single enable for write, with reads on no write
|
||||||
|
params={"ADDRESS_WIDTH": 10, "DATA_WIDTH": 36},
|
||||||
|
top="sync_ram_tdp",
|
||||||
|
assertions=[],
|
||||||
|
test_steps=[
|
||||||
|
{"wce_a": 1, "ra_a": 0x0A, "wce_b": 1, "ra_b": 0xBA,
|
||||||
|
"wd_a": 0xdeadbeef, "wd_b": 0x5a5a5a5a},
|
||||||
|
{"wce_a": 1, "ra_a": 0xBA, "rce_b": 1, "ra_b": 0xBA,
|
||||||
|
"wd_a": 0xa5a5a5a5},
|
||||||
|
{ "rq_b": 0x5a5a5a5a},
|
||||||
|
{"rce_a": 1, "ra_a": 0x0A, "rce_b": 1, "ra_b": 0x0A},
|
||||||
|
{"rq_a": 0xdeadbeef, "rq_b": 0xdeadbeef},
|
||||||
|
{ "rce_b": 1, "ra_b": 0xBA},
|
||||||
|
{ "rq_b": 0xa5a5a5a5},
|
||||||
|
]
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
for (params, top, assertions) in blockram_tests:
|
for (params, top, assertions) in blockram_tests:
|
||||||
|
@ -225,6 +306,8 @@ for sim_test in sim_tests:
|
||||||
if test_steps:
|
if test_steps:
|
||||||
if top == "sync_ram_sdp":
|
if top == "sync_ram_sdp":
|
||||||
uut_submodule = sync_ram_sdp_submodule
|
uut_submodule = sync_ram_sdp_submodule
|
||||||
|
elif top == "sync_ram_tdp":
|
||||||
|
uut_submodule = sync_ram_tdp_submodule
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError(f"missing submodule header for {top}")
|
raise NotImplementedError(f"missing submodule header for {top}")
|
||||||
mem_test_vector = ""
|
mem_test_vector = ""
|
||||||
|
|
|
@ -43,6 +43,7 @@ end
|
||||||
|
|
||||||
wire rce_a = rce_a_testvector[i];
|
wire rce_a = rce_a_testvector[i];
|
||||||
wire [ADDRESS_WIDTH-1:0] ra_a = ra_a_testvector[i];
|
wire [ADDRESS_WIDTH-1:0] ra_a = ra_a_testvector[i];
|
||||||
|
wire [DATA_WIDTH-1:0] rq_a_e = rq_a_expected[i];
|
||||||
wire [DATA_WIDTH-1:0] rq_a;
|
wire [DATA_WIDTH-1:0] rq_a;
|
||||||
|
|
||||||
wire wce_a = wce_a_testvector[i];
|
wire wce_a = wce_a_testvector[i];
|
||||||
|
@ -51,6 +52,7 @@ wire [DATA_WIDTH-1:0] wd_a = wd_a_testvector[i];
|
||||||
|
|
||||||
wire rce_b = rce_b_testvector[i];
|
wire rce_b = rce_b_testvector[i];
|
||||||
wire [ADDRESS_WIDTH-1:0] ra_b = ra_b_testvector[i];
|
wire [ADDRESS_WIDTH-1:0] ra_b = ra_b_testvector[i];
|
||||||
|
wire [DATA_WIDTH-1:0] rq_b_e = rq_b_expected[i];
|
||||||
wire [DATA_WIDTH-1:0] rq_b;
|
wire [DATA_WIDTH-1:0] rq_b;
|
||||||
|
|
||||||
wire wce_b = wce_b_testvector[i];
|
wire wce_b = wce_b_testvector[i];
|
||||||
|
@ -63,9 +65,9 @@ always @(posedge clk) begin
|
||||||
if (i < VECTORLEN-1) begin
|
if (i < VECTORLEN-1) begin
|
||||||
if (i > 0) begin
|
if (i > 0) begin
|
||||||
if($past(rce_a))
|
if($past(rce_a))
|
||||||
assert(rq_a == rq_a_expected[i]);
|
assert(rq_a == rq_a_e);
|
||||||
if($past(rce_b))
|
if($past(rce_b))
|
||||||
assert(rq_b == rq_b_expected[i]);
|
assert(rq_b == rq_b_e);
|
||||||
end
|
end
|
||||||
i <= i + 1;
|
i <= i + 1;
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue