From 1f53450aaad230d4e36d79003b8aa449eb70b80d Mon Sep 17 00:00:00 2001 From: developer Date: Wed, 12 Jun 2024 14:05:45 +0200 Subject: [PATCH] Added burst write bus --- .../src/axi_master.vhd | 86 +++++++++++-------- .../test/tb_axi_master.vhd | 16 +++- 2 files changed, 65 insertions(+), 37 deletions(-) diff --git a/vunit/vhdl/verification_components/src/axi_master.vhd b/vunit/vhdl/verification_components/src/axi_master.vhd index 837488dfd..ad82aded7 100644 --- a/vunit/vhdl/verification_components/src/axi_master.vhd +++ b/vunit/vhdl/verification_components/src/axi_master.vhd @@ -132,11 +132,16 @@ begin end if; end procedure; - function get_full_size return std_logic_vector is + function get_full_read_size return std_logic_vector is begin return std_logic_vector(to_unsigned(integer(ceil(log2(real(rdata'length/8)))), arsize'length)); end function; + function get_full_write_size return std_logic_vector is + begin + return std_logic_vector(to_unsigned(integer(ceil(log2(real(wdata'length/8)))), awsize'length)); + end function; + variable rnd : RandomPType; variable request_msg : msg_t; variable msg_type : msg_type_t; @@ -174,12 +179,12 @@ begin if msg_type = bus_read_msg then len := 0; - size := get_full_size; + size := get_full_read_size; burst := axi_burst_type_fixed; id(id'range) := (others => '0'); elsif msg_type = bus_burst_read_msg then len := pop_integer(request_msg) - 1; -- bring bus burst down to axi zero based indexing - size := get_full_size; + size := get_full_read_size; burst := axi_burst_type_incr; id(id'range) := (others => '0'); elsif msg_type = axi_read_msg then @@ -225,74 +230,92 @@ begin end loop; addr := pop_std_ulogic_vector(request_msg); - data := pop_std_ulogic_vector(request_msg); - byteenable := pop_std_ulogic_vector(request_msg); if msg_type = bus_write_msg then + data := pop_std_ulogic_vector(request_msg); + byteenable := pop_std_ulogic_vector(request_msg); len := 0; - size := get_full_size; + size := get_full_write_size; burst := axi_burst_type_fixed; id(id'range) := (others => '0'); - elsif msg_type = bus_burst_write_msg then + elsif msg_type = bus_burst_write_msg then + byteenable(byteenable'range) := (others => '1'); -- not set in bus master pkg len := pop_integer(request_msg) - 1; -- bring bus burst down to axi zero based indexing - size := get_full_size; + data := pop_std_ulogic_vector(request_msg); + size := get_full_write_size; burst := axi_burst_type_incr; id(id'range) := (others => '0'); elsif msg_type = axi_write_msg then + data := pop_std_ulogic_vector(request_msg); + byteenable := pop_std_ulogic_vector(request_msg); len := 0; size := pop_std_ulogic_vector(request_msg); burst := axi_burst_type_fixed; id := pop_std_ulogic_vector(request_msg)(arid'length -1 downto 0); elsif msg_type = axi_burst_write_msg then + data := pop_std_ulogic_vector(request_msg); + byteenable := pop_std_ulogic_vector(request_msg); len := to_integer(unsigned(pop_std_ulogic_vector(request_msg))); size := pop_std_ulogic_vector(request_msg); burst := pop_std_ulogic_vector(request_msg); id := pop_std_ulogic_vector(request_msg)(arid'length -1 downto 0); end if; - awaddr <= addr; - push_std_ulogic_vector(request_msg, addr); + resp := pop_std_ulogic_vector(request_msg) when is_axi_msg(msg_type) else axi_resp_okay; + + w_done := false; + aw_done := false; + -- first iteration + awvalid <= '1'; + awaddr <= addr; awlen <= std_logic_vector(to_unsigned(len, awlen'length)); awsize <= size; awburst <= burst; - awid <= id; - push_std_ulogic_vector(request_msg, id); + wvalid <= '1'; wdata <= data; - push_std_ulogic_vector(request_msg, data); - wstrb <= byteenable; - wlast <= '1'; - - resp := pop_std_ulogic_vector(request_msg) when is_axi_msg(msg_type) else axi_resp_okay; - push_std_ulogic_vector(request_msg, resp); - push(write_reply_queue, request_msg); - - wvalid <= '1'; - awvalid <= '1'; + wlast <= '1' when len = 0 else '0'; - w_done := false; - aw_done := false; while not (w_done and aw_done) loop wait until ((awvalid and awready) = '1' or (wvalid and wready) = '1') and rising_edge(aclk); if (awvalid and awready) = '1' then awvalid <= '0'; drive_aw_invalid; - aw_done := true; end if; if (wvalid and wready) = '1' then - wvalid <= '0'; - drive_w_invalid; - w_done := true; + if len = 0 then + wvalid <= '0'; + drive_w_invalid; + w_done := true; + else + -- burst iterations + len := len - 1; + data := pop_std_ulogic_vector(request_msg); + wdata <= data; + wstrb <= byteenable; + wlast <= '1' when len = 0 else '0'; + end if; + + if is_visible(bus_handle.p_logger, debug) then + debug(bus_handle.p_logger, + "Wrote 0x" & to_hstring(data) & + " to address 0x" & to_hstring(addr)); + end if; end if; + end loop; + push_std_ulogic_vector(request_msg, addr); + push_std_ulogic_vector(request_msg, id); + push_std_ulogic_vector(request_msg, resp); + push(write_reply_queue, request_msg); else unexpected_msg_type(msg_type); @@ -378,18 +401,11 @@ begin msg_type := message_type(request_msg); addr := pop_std_ulogic_vector(request_msg); id := pop_std_ulogic_vector(request_msg); - data := pop_std_ulogic_vector(request_msg); resp := pop_std_ulogic_vector(request_msg); check_axi_id(bus_handle, bid, id, "bid"); check_axi_resp(bus_handle, bresp, resp, "bresp"); - if is_visible(bus_handle.p_logger, debug) then - debug(bus_handle.p_logger, - "Wrote 0x" & to_hstring(data) & - " to address 0x" & to_hstring(addr)); - end if; - delete(request_msg); end process; diff --git a/vunit/vhdl/verification_components/test/tb_axi_master.vhd b/vunit/vhdl/verification_components/test/tb_axi_master.vhd index 5f7051577..8563d7dfc 100644 --- a/vunit/vhdl/verification_components/test/tb_axi_master.vhd +++ b/vunit/vhdl/verification_components/test/tb_axi_master.vhd @@ -211,7 +211,7 @@ begin for n in 0 to 4 loop info(tb_logger, "Setup..."); burst := 1; - setup_and_set_random_data_write_memory(memory, burst, rdata'length, memory_data_queue); + setup_and_set_random_data_write_memory(memory, burst, wdata'length, memory_data_queue); info(tb_logger, "Reading..."); write_bus(net, bus_handle, 0, pop(memory_data_queue)); info(tb_logger, "Compare..."); @@ -223,13 +223,25 @@ begin for n in 0 to 4 loop info(tb_logger, "Setup..."); burst := 1; - setup_and_set_random_data_write_memory(memory, burst, rdata'length, memory_data_queue); + setup_and_set_random_data_write_memory(memory, burst, wdata'length, memory_data_queue); info(tb_logger, "Reading..."); write_axi(net, bus_handle, x"00000000", pop(memory_data_queue), "001", x"25", axi_resp_okay); info(tb_logger, "Compare..."); check_true(is_empty(memory_data_queue), "memory_data_queue not flushed"); wait_on_data_write_memory(memory); end loop; + + elsif run("Test random burstcount write with burst_write_bus") then + for n in 0 to 4 loop + info(tb_logger, "Setup..."); + burst := rnd.RandInt(1, 255); + setup_and_set_random_data_write_memory(memory, burst, wdata'length, memory_data_queue); + info(tb_logger, "Reading..."); + burst_write_bus(net, bus_handle, x"00000000", burst, memory_data_queue); + info(tb_logger, "Compare..."); + check_true(is_empty(memory_data_queue), "memory_data_queue not flushed"); + wait_on_data_write_memory(memory); + end loop; end if; wait for 100 ns;