Commit 0220f91f authored by Dimitris Lampridis's avatar Dimitris Lampridis

hdl: fix behaviour of L2P DMA master when wishbone stalls.

Signed-off-by: Dimitris Lampridis's avatarDimitris Lampridis <dimitris.lampridis@cern.ch>
parent 99356c44
......@@ -28,7 +28,7 @@ Changed
- hdl: Use cheby to describe registers, only one interrupt (level).
- hdl: Test, verify and enable byte swap feature.
- hdl: Extend SV BFM with tasks to read/write from simulated host memory.
Fixed
-----
- hdl: Fixed incorrect 64-bit DMA transaction generation bug.
......
......@@ -96,7 +96,7 @@ architecture arch of l2p_dma_master is
L2P_NEXT, L2P_ERROR);
signal l2p_dma_current_state : l2p_dma_state_type := L2P_IDLE;
type wb_dma_state_type is (WB_IDLE, WB_SETUP, WB_DATA, WB_HOLD);
type wb_dma_state_type is (WB_IDLE, WB_SETUP, WB_DATA1,WB_DATA2, WB_HOLD);
signal wb_dma_current_state : wb_dma_state_type := WB_IDLE;
signal dma_target_addr : unsigned(29 downto 0) := (others => '0');
......@@ -127,10 +127,6 @@ architecture arch of l2p_dma_master is
signal wb_dma_cyc : std_logic := '0';
signal wb_dma_stb : std_logic := '0';
signal wb_dma_addr : unsigned(29 downto 0) := (others => '0');
signal wb_dma_addr_d : unsigned(29 downto 0) := (others => '0');
signal wb_dma_cnt_stb : unsigned(29 downto 0) := (others => '0');
signal wb_dma_cnt_ack : unsigned(29 downto 0) := (others => '0');
signal wb_dma_fsm_en : std_logic := '0';
signal wb_dma_fsm_en_sync : std_logic := '0';
......@@ -385,7 +381,6 @@ begin
wb_dma_o.cyc <= wb_dma_cyc;
wb_dma_o.stb <= wb_dma_stb;
wb_dma_o.adr <= "00" & std_logic_vector(wb_dma_addr_d);
wb_dma_o.we <= '0';
wb_dma_o.sel <= (others => '1');
wb_dma_o.dat <= (others => '0');
......@@ -397,21 +392,19 @@ begin
data_fifo_wr <= wb_dma_i.ack;
p_wb_fsm : process (wb_dma_clk_i)
variable wb_dma_addr : unsigned(29 downto 0) := (others => '0');
variable wb_dma_cnt_stb : unsigned(29 downto 0) := (others => '0');
variable wb_dma_cnt_ack : unsigned(29 downto 0) := (others => '0');
begin
if rising_edge(wb_dma_clk_i) then
if wb_dma_rst_n_i = '0' or wb_dma_fsm_en_sync = '0' then
wb_dma_cyc <= '0';
wb_dma_stb <= '0';
wb_dma_addr <= (others => '0');
wb_dma_addr := (others => '0');
wb_dma_o.adr <= (others => '0');
wb_dma_current_state <= WB_IDLE;
else
wb_dma_addr_d <= wb_dma_addr;
-- default values if not overriden by current state
wb_dma_stb <= '0';
wb_dma_cyc <= '0';
case wb_dma_current_state is
when WB_IDLE =>
......@@ -420,39 +413,60 @@ begin
end if;
when WB_SETUP =>
wb_dma_addr <= unsigned(dma_param_sync(59 downto 30));
wb_dma_cnt_stb <= unsigned(dma_param_sync(29 downto 0));
wb_dma_cnt_ack <= unsigned(dma_param_sync(29 downto 0));
wb_dma_addr := unsigned(dma_param_sync(59 downto 30));
wb_dma_cnt_stb := unsigned(dma_param_sync(29 downto 0));
wb_dma_cnt_ack := unsigned(dma_param_sync(29 downto 0));
if data_fifo_full = '0' then
wb_dma_current_state <= WB_DATA;
wb_dma_current_state <= WB_DATA1;
end if;
when WB_DATA =>
when WB_DATA1 =>
wb_dma_cyc <= '1';
if wb_dma_i.ack = '1' then
wb_dma_cnt_ack <= wb_dma_cnt_ack - 1;
wb_dma_cnt_ack := wb_dma_cnt_ack - 1;
end if;
if data_fifo_full = '1' then
wb_dma_stb <= '0';
wb_dma_current_state <= WB_HOLD;
elsif wb_dma_cnt_ack = 0 and wb_dma_cnt_stb = 0 then
wb_dma_current_state <= WB_IDLE;
else
if wb_dma_cnt_stb > 0 then
wb_dma_stb <= '1';
if wb_dma_i.stall = '0' then
wb_dma_addr <= wb_dma_addr + 1;
wb_dma_cnt_stb <= wb_dma_cnt_stb - 1;
if wb_dma_i.stall = '0' then
wb_dma_o.adr <= "00" & std_logic_vector(wb_dma_addr);
wb_dma_addr := wb_dma_addr + 1;
if wb_dma_cnt_stb = 0 then
wb_dma_stb <= '0';
wb_dma_current_state <= WB_DATA2;
else
wb_dma_cnt_stb := wb_dma_cnt_stb - 1;
wb_dma_stb <= '1';
end if;
end if;
end if;
when WB_DATA2 =>
wb_dma_cyc <= '1';
if wb_dma_i.ack = '1' then
wb_dma_cnt_ack := wb_dma_cnt_ack - 1;
end if;
if data_fifo_full = '1' then
wb_dma_stb <= '0';
wb_dma_current_state <= WB_HOLD;
elsif wb_dma_cnt_ack = 0 then
wb_dma_cyc <= '0';
wb_dma_current_state <= WB_IDLE;
end if;
when WB_HOLD =>
wb_dma_cyc <= '1';
wb_dma_stb <= '0';
if wb_dma_i.ack = '1' then
wb_dma_cnt_ack <= wb_dma_cnt_ack - 1;
wb_dma_cnt_ack := wb_dma_cnt_ack - 1;
end if;
if data_fifo_full = '0' then
wb_dma_current_state <= WB_DATA;
if wb_dma_cnt_stb = 0 then
wb_dma_current_state <= WB_DATA2;
else
wb_dma_current_state <= WB_DATA1;
end if;
end if;
when others =>
......
......@@ -166,8 +166,10 @@ module main;
initial begin
int stall_cycle[14];
automatic int ntest = 1;
const int tests = 11;
const int tests = 12;
uint32_t addr, val, expected;
......@@ -320,6 +322,47 @@ module main;
$write("PASS\n");
// ---------------------------------
$write("Test %0d/%0d: 256B DMA reads with stalling: ",
ntest++, tests);
// Setup DMA
acc.write('h14, 'h100); // count
acc.write('h20, 'h00); // attrib
acc.write('h0c, 'h20000000); // hstartL
acc.write('h10, 'h00000000); // hstartH
stall_cycle = '{0,1,2,14,15,16,17,30,31,32,33,61,62,63};
foreach(stall_cycle[i])
begin
acc.write('h00, 'h01); // start
@(posedge wb_dma_out.stb);
repeat(stall_cycle[i]) @(posedge clk_125m);
force DUT.cmp_wrapped_gn4124.dma_stall_i = 1'b1;
@(posedge clk_125m);
force DUT.cmp_wrapped_gn4124.dma_ack_i = 1'b0;
@(posedge clk_125m);
release DUT.cmp_wrapped_gn4124.dma_stall_i;
@(posedge clk_125m);
release DUT.cmp_wrapped_gn4124.dma_ack_i;
@(posedge dma_irq);
check_irq_status;
clear_irq;
for (addr = 'h00; addr < 'h40; addr += 1)
begin
expected = 32'h80000020 - addr;
mem_check(4 * addr, expected);
end
repeat(4) @(posedge clk_125m);
end
$write("PASS\n");
// ---------------------------------
$write("Test %0d/%0d: 2x4KiB chained DMA write: ",
ntest++, tests);
......
......@@ -2,10 +2,11 @@ onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/wb_dma_clk_i
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/wb_dma_current_state
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/wb_dma_cnt_stb
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/wb_dma_o
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/wb_dma_cnt_ack
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/wb_dma_i
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/p_wb_fsm/wb_dma_addr
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/p_wb_fsm/wb_dma_cnt_stb
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/p_wb_fsm/wb_dma_cnt_ack
add wave -noupdate -expand -group L2P -expand /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/wb_dma_o
add wave -noupdate -expand -group L2P -expand /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/wb_dma_i
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/data_fifo_wr
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/data_fifo_full
add wave -noupdate -expand -group L2P /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/data_fifo_din
......@@ -31,7 +32,6 @@ add wave -noupdate -expand -group P2L /main/DUT/cmp_wrapped_gn4124/gen_with_dma/
add wave -noupdate -expand -group P2L /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/to_wb_fifo_empty
add wave -noupdate -expand -group P2L /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/to_wb_fifo_rd
add wave -noupdate -expand -group P2L /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/to_wb_fifo_dout
add wave -noupdate -expand -group P2L /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/to_wb_fifo_valid
add wave -noupdate -expand -group P2L /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/wb_dma_o
add wave -noupdate -expand -group P2L /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/wb_dma_i
add wave -noupdate -expand -group {DMA Controller} -color Thistle /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/wb_clk_i
......@@ -56,7 +56,7 @@ add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wra
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_len_o
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_byte_swap_o
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {6339711 ps} 0} {{Cursor 2} {129899342 ps} 1}
WaveRestoreCursors {{Cursor 1} {226705189 ps} 0} {{Cursor 2} {129899342 ps} 1}
quietly wave cursor active 1
configure wave -namecolwidth 277
configure wave -valuecolwidth 210
......@@ -72,4 +72,4 @@ configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {0 ps} {24072512 ps}
WaveRestoreZoom {0 ps} {611801400 ps}
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