Commit d601caf2 authored by Dimitris Lampridis's avatar Dimitris Lampridis Committed by Tristan Gingold

[sim] update BFM and testbench to be able to do proper DMA reads/writes

parent e13fe484
......@@ -130,6 +130,12 @@ module main;
val_check("Register read-back", addr, val, expected);
endtask // reg_check
task mem_check(uint32_t addr, expected);
uint64_t val;
i_gn4124.host_mem_read(addr, val);
val_check("Memory read-back", addr, val, expected);
endtask // reg_check
initial begin
automatic int ntest = 1;
......@@ -168,9 +174,6 @@ module main;
$write("Test %0d/%0d: 32 reads over DMA, abort after first read: ",
ntest++, tests);
// Perform 32 reads over DMA
reg_check('h00, 'h00000000);
if (dma_irq != 1'b0)
$fatal(1, "dma irq should be 0");
......@@ -198,48 +201,93 @@ module main;
$write("PASS\n");
$write("Test %0d/%0d: 2x32 chained reads over DMA: ",
ntest++, tests);
// Setup DMA chain info in BFM memory
i_gn4124.host_mem_write('h20000, 'h00000000); // remote address
i_gn4124.host_mem_write('h20004, 'h20000100); // hstartL
i_gn4124.host_mem_write('h20008, 'h00000000); // hstartH
i_gn4124.host_mem_write('h2000C, 'h80); // count
i_gn4124.host_mem_write('h20010, 'h00); // nextL
i_gn4124.host_mem_write('h20014, 'h00); // nextH
i_gn4124.host_mem_write('h20018, 'h00); // attrib
acc.write('h14, 'h80); // count
acc.write('h20, 'h02); // attrib
acc.write('h0c, 'h20000000); // hstartL
acc.write('h10, 'h00000000); // hstartH
// Point to chain info in BFM memory
acc.write('h18, 'h20020000); // nextL
acc.write('h1C, 'h00000000); // nextH
acc.write('h00, 'h01); // start
@(posedge dma_irq);
// Check irq status
reg_check('h04, 'h04);
if (dma_irq != 1'b1)
$fatal(1, "dma irq should be 1");
for (addr = 'h00; addr < 'h20; addr += 1)
begin
expected = 32'h80000000 + 'h20 - addr - 1;
mem_check(4 * addr, expected);
mem_check('h100 + 4 * addr, expected);
end
// clear irq
acc.write('h04, 'h04);
reg_check('h04, 'h00);
if (dma_irq != 1'b0)
$fatal(1, "dma irq should be 0");
repeat(4) @(posedge clk_125m);
$write("PASS\n");
// Check all four byte swap settings
for (int i = 0; i < 4; i++) begin
$write("Test %0d/%0d: 32 reads over DMA (byte swap = %0d): ",
ntest++, tests, i);
// Restart
acc.write('h14, 'h80); // count
acc.write('h14, 'h1000); // count
acc.write('h20, 'h00); // attrib
acc.write('h0c, 'h20000000 + i * 'h1000); // hstartL
acc.write('h10, 'h00000000); // hstartH
acc.write('h00, (i << 2) | 'h01); // start
@(posedge i_gn4124.l2p_valid); // skip header
@(posedge i_gn4124.l2p_valid);
@(posedge dma_irq);
// Check irq status
reg_check('h04, 'h04);
if (dma_irq != 1'b1)
$fatal(1, "dma irq should be 1");
for (addr = 'h20; addr > 'h00; addr -= 1)
for (addr = 'h00; addr < 'h400; addr += 1)
begin
expected = 32'h80000000 + addr - 1;
expected = 32'h80000000 + 'h20 - (addr % 'h20) - 1;
if (i == 1)
expected = {<<8{expected}};
else if (i == 2)
expected = {<<16{expected}};
else if (i == 3)
expected = {<<16{{<<8{expected}}}};
val = i_gn4124.l2p_data;
@(posedge i_gn4124.l2p_clk_n);
val |= i_gn4124.l2p_data << 16;
val_check("DMA read-back", 'h20-addr, val, expected);
@(posedge i_gn4124.l2p_clk_p);
mem_check((i * 'h1000) + 4 * addr, expected);
end
//#1us;
repeat(4) @(posedge clk_125m);
// Check irq status
reg_check('h04, 'h04);
if (dma_irq != 1'b1)
$fatal(1, "dma irq should be 1");
// clear irq
acc.write('h04, 'h04);
reg_check('h04, 'h00);
if (dma_irq != 1'b0)
$fatal(1, "dma irq should be 0");
repeat(4) @(posedge clk_125m);
$write("PASS\n");
#1us;
......
......@@ -158,6 +158,22 @@ GN412X_BFM
endtask // readback
task host_mem_write(uint64_t addr, uint64_t data);
string cmd;
$sformat(cmd,"wr 00000000%08X F %08X", 'h20000000 + addr, data);
send_cmd(cmd);
endtask // host_mem_write
task automatic host_mem_read(uint64_t addr, ref uint64_t data);
string cmd;
$sformat(cmd,"rd 00000000%08X F", 'h20000000 + addr);
fork
send_cmd(cmd);
readback(data);
join
endtask // host_mem_read
class CBusAccessor_Gennum extends CBusAccessor;
......@@ -169,12 +185,9 @@ class CBusAccessor_Gennum extends CBusAccessor;
string cmd;
int i;
if(size != 4)
size = 4;
// $fatal("CBusAccessor_Gennum: only size=4 supported");
for(i=0;i<addr.size();i++)
begin
$sformat(cmd,"wr FF000000%08X F %08X", addr[i], data[i]);
......@@ -187,13 +200,9 @@ class CBusAccessor_Gennum extends CBusAccessor;
int i;
uint64_t tmp;
if(size != 4)
size = 4;
// $fatal("CBusAccessor_Gennum: only size=4 supported");
for(i=0;i<addr.size();i++)
begin
$sformat(cmd,"rd FF000000%08X F", addr[i]);
......@@ -297,5 +306,5 @@ endinterface
.gn_tx_error_i (IF_NAME.tx_error),\
.gn_vc_rdy_i (IF_NAME.vc_rdy),\
.gn_gpio_b ()
`endif // `ifndef __GN4124_BFM_SVH
......@@ -43,8 +43,8 @@ entity GN412X_BFM is
CMD_REQ : in bit;
CMD_ACK : out bit;
CMD_CLOCK_EN : in boolean;
CMD_RD_DATA: out std_ulogic_vector(31 downto 0);
CMD_RD_DATA_VALID: out std_logic;
CMD_RD_DATA : out std_ulogic_vector(31 downto 0);
CMD_RD_DATA_VALID : out std_logic;
--=========================================================--
-------------------------------------------------------------
-- GN412x Signal I/O
......@@ -598,6 +598,9 @@ architecture MODEL of GN412X_BFM is
signal IN_DFRAME : std_ulogic;
signal IN_VALID : std_ulogic;
signal Q_IN_DFRAME : std_ulogic;
signal CMD_RD_DATA_IN : std_ulogic_vector(31 downto 0);
signal CMD_RD_DATA_IN_VALID : std_logic;
-----------------------------------------------------------------------------
-- Signals Related to the OutBound Process
-----------------------------------------------------------------------------
......@@ -607,6 +610,8 @@ architecture MODEL of GN412X_BFM is
signal OUT_WR_REQ : std_ulogic_vector(P_WR_REQ'range);
signal OUT_WR_RDY : std_ulogic_vector(P_WR_RDY'range);
signal Q_OUT_WR_RDY : std_ulogic_vector(P_WR_RDY'range);
signal CMD_RD_DATA_OUT : std_ulogic_vector(31 downto 0);
signal CMD_RD_DATA_OUT_VALID : std_logic;
......@@ -1013,6 +1018,8 @@ CMD <= f_cmd_to_string(CMD_INT);
INBOUND_READ_REQUEST_CPL_STATE <= (others => false);
loop
CMD_RD_DATA_OUT_VALID <= '0';
CMD_ACK <= '0';
wait on CMD_REQ, CLK;
......@@ -1675,7 +1682,12 @@ writeline(OUT_FILE, OUTPUT_LINE);
if(vERR = 1) then writeline(OUT_FILE, OUTPUT_LINE); end if;
CMD_RD_DATA_OUT <= DATA_TMP32;
CMD_RD_DATA_OUT_VALID <= '1';
wait for 1 ns;
CMD_RD_DATA_OUT_VALID <= '0';
end if;
else
......@@ -2326,7 +2338,7 @@ writeline(OUT_FILE, OUTPUT_LINE);
RD_BUFFER_PTR := (others => 0);
loop
CMD_RD_DATA_VALID <= '0';
CMD_RD_DATA_IN_VALID <= '0';
wait until(ICLK'event and (ICLK = '1'));
......@@ -2544,11 +2556,11 @@ writeline(OUT_FILE, OUTPUT_LINE);
CMP_DATA := IN_DATA;
CMD_RD_DATA <= IN_DATA;
CMD_RD_DATA_VALID <= '1';
CMD_RD_DATA_IN <= IN_DATA;
CMD_RD_DATA_IN_VALID <= '1';
wait for 1 ns;
CMD_RD_DATA_VALID <= '0';
CMD_RD_DATA_IN_VALID <= '0';
RD_DATA := RD_BUFFER(I_CID).DATA(RD_BUFFER_PTR(I_CID));
......@@ -2608,6 +2620,17 @@ writeline(OUT_FILE, OUTPUT_LINE);
end loop;
end process;
--#########################################################################--
--
-- Command read multiplexer
--
-- Choose between data from local BFM memory and device for read commands
--
--#########################################################################--
CMD_RD_DATA_VALID <= CMD_RD_DATA_IN_VALID or CMD_RD_DATA_OUT_VALID;
CMD_RD_DATA <= CMD_RD_DATA_OUT when CMD_RD_DATA_OUT_VALID = '1' else CMD_RD_DATA_IN;
--#########################################################################--
--
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment