Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • project/gn4124-core
1 result
Show changes
Showing
with 406 additions and 1232 deletions
vsim -quiet -L unisim -classdebug -voptargs=+acc work.main
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
radix -hexadecimal
log -r /*
run -all
......@@ -5,6 +5,4 @@ set NumericStdNoWarnings 1
radix -hexadecimal
log -r /*
run -all
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/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
add wave -noupdate -expand -group L2P -color Magenta /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/clk_i
add wave -noupdate -expand -group L2P -color Magenta /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/data_fifo_empty
add wave -noupdate -expand -group L2P -color Magenta /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/data_fifo_rd
add wave -noupdate -expand -group L2P -color Magenta /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/data_fifo_dout
add wave -noupdate -expand -group L2P -color Magenta /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/dma_packet_len
add wave -noupdate -expand -group L2P -color Magenta /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/l2p_dma_current_state
add wave -noupdate -expand -group L2P -color Magenta /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/ldm_arb_valid_o
add wave -noupdate -expand -group L2P -color Magenta /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/ldm_arb_dframe_o
add wave -noupdate -expand -group L2P -color Magenta /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_l2p_dma_master/ldm_arb_data_o
add wave -noupdate -expand -group P2L -color {Indian Red} /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/clk_i
add wave -noupdate -expand -group P2L -color {Indian Red} /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/p2l_dma_current_state
add wave -noupdate -expand -group P2L -color {Indian Red} /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/target_addr_cnt
add wave -noupdate -expand -group P2L -color {Indian Red} /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/pd_pdm_data_valid_i
add wave -noupdate -expand -group P2L -color {Indian Red} /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/pd_pdm_data_i
add wave -noupdate -expand -group P2L -color {Indian Red} /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/to_wb_fifo_wr_d
add wave -noupdate -expand -group P2L -color {Indian Red} /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/to_wb_fifo_din_d
add wave -noupdate -expand -group P2L -color {Indian Red} /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/to_wb_fifo_full
add wave -noupdate -expand -group P2L -color {Indian Red} /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/p2l_rdy_o
add wave -noupdate -expand -group P2L /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_p2l_dma_master/wb_dma_clk_i
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/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
add wave -noupdate -expand -group {DMA Controller} -color Thistle /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/wb_cyc_i
add wave -noupdate -expand -group {DMA Controller} -color Thistle /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/wb_stb_i
add wave -noupdate -expand -group {DMA Controller} -color Thistle /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/wb_we_i
add wave -noupdate -expand -group {DMA Controller} -color Thistle /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/wb_ack_o
add wave -noupdate -expand -group {DMA Controller} -color Thistle /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/wb_adr_i
add wave -noupdate -expand -group {DMA Controller} -color Thistle /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/wb_dat_i
add wave -noupdate -expand -group {DMA Controller} -color Thistle /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/wb_dat_o
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_start_l2p_o
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_start_p2l_o
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_start_next_o
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_abort_o
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_error_i
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_done_i
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_irq_o
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_direction_o
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_carrier_addr_o
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_host_addr_h_o
add wave -noupdate -expand -group {DMA Controller} -color Cyan /main/DUT/cmp_wrapped_gn4124/gen_with_dma/cmp_dma_controller/dma_ctrl_host_addr_l_o
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} {226705189 ps} 0} {{Cursor 2} {129899342 ps} 1}
quietly wave cursor active 1
configure wave -namecolwidth 277
configure wave -valuecolwidth 210
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {0 ps} {611801400 ps}
......@@ -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
......@@ -181,7 +181,6 @@ architecture MODEL of GN412X_BFM is
--=========================================================================--
procedure sget_boolean(S : in string; P : inout integer; X : out boolean) is
variable char : character;
variable q : integer;
begin
if(S'length > P) then
char := S(P);
......@@ -235,22 +234,6 @@ architecture MODEL of GN412X_BFM is
-- return(SRI);
-- end next_random;
--=========================================================================--
-- Produce Another Random Number
--
-- RNDOUT is a number between MIN and MAX. SR must be stored and fed back each call.
--=========================================================================--
procedure get_random(SR : inout integer; min : in integer; MAX : in integer; RNDOUT : out integer) is
variable SRV : std_ulogic_vector(22 downto 0);
variable SRI : integer;
begin
SRV := To_Vector(SR, SRV'length);
SRV := SRV(21 downto 0) & (SRV(22) xor SRV(17));
SRI := conv_integer(SRV);
RNDOUT := min + (SRI mod (MAX - min + 1));
SR := SRI;
end get_random;
--=========================================================================--
-- Test a Random Number and test it
--
......@@ -366,11 +349,6 @@ architecture MODEL of GN412X_BFM is
-----------------------------------------------------------------------------
-- Top Level I/O signals SECONDARY MODE
-----------------------------------------------------------------------------
-------------------------------------------------------------
----------------- Local Bus Clock ---------------------------
-------------------------------------------------------------
--
signal LCLKi, LCLKni : std_ulogic;
-------------------------------------------------------------
----------------- Local-to-PCI Dataflow ---------------------
-------------------------------------------------------------
......@@ -416,7 +394,6 @@ architecture MODEL of GN412X_BFM is
-- Used by the Inbound State Machine
--
signal ICLK : std_ulogic; -- Internal Inbound clock
signal LCLK_PERIOD : time := T_LCLK;
-----------------------------------------------------------------------------
-- Internal Model Signals
......@@ -544,9 +521,6 @@ architecture MODEL of GN412X_BFM is
-- signal WR_BUFFER : WR_BUFFER_ARRAY_TYPE;
signal RANDOM_NUMBER : integer := 0;
-------------------------------------------------------------------------
-- Data Structure used to store info about BARs that generate outbound
-- read/write packets
......@@ -598,6 +572,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 +584,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;
......@@ -625,7 +604,7 @@ CMD <= f_cmd_to_string(CMD_INT);
--=========================================================================--
-- Generate the Internal LCLK
--=========================================================================--
process
gen_int_clk: process
begin
CLK0o <= '0';
CLK90o <= '0';
......@@ -642,7 +621,7 @@ CMD <= f_cmd_to_string(CMD_INT);
wait until(CMD_CLOCK_EN'event and CMD_CLOCK_EN and PRIMARY);
end if;
end loop;
end process;
end process gen_int_clk;
PRIMARY <= MODE_PRIMARY;
SECONDARY <= not MODE_PRIMARY;
......@@ -910,15 +889,13 @@ CMD <= f_cmd_to_string(CMD_INT);
-- (Handles TX from the BFM: P2L for Primary and L2P for secondary)
--
--#########################################################################--
process
p_out_fsm: process
--file OUT_FILE : text is out "STD_OUTPUT";
file OUT_FILE : text open write_mode is "NullFile";
variable OUTPUT_LINE : line;
variable ERR_CNT : integer;
variable L_CMD : string(1 to 80);
variable TMP_STR : string(1 to 80);
variable QCMD : string(CMD'range);
variable L_NUM : integer;
variable L_ADDR : std_ulogic_vector(63 downto 0);
variable L_BE : std_ulogic_vector(3 downto 0);
variable L_DATA : std_ulogic_vector(31 downto 0);
......@@ -940,7 +917,6 @@ CMD <= f_cmd_to_string(CMD_INT);
variable CURRENT_VC : integer;
variable IWAIT_RANDOM : integer;
variable IWAIT_RANDOM_N : integer;
variable RNDNUM : integer;
variable BAR_HIT : boolean_vector(1 downto 0);
variable BFM_BAR_HIT : boolean_vector(1 downto 0);
variable DATA_TMP8 : std_ulogic_vector(7 downto 0);
......@@ -967,11 +943,6 @@ CMD <= f_cmd_to_string(CMD_INT);
variable RD_TYPE : std_ulogic_vector(3 downto 0);
variable RW_BLAST : boolean;
--
-- OUT variables
variable OUT_NOSNOOP : std_ulogic;
-- variable OUT_VC : std_ulogic;
variable OUT_TC : std_ulogic_vector(2 downto 0);
--
-- Read Completion Management
......@@ -984,10 +955,6 @@ CMD <= f_cmd_to_string(CMD_INT);
variable IWAIT_RND_SEED : integer;
variable DEBUG : integer;
begin
-- Signal Initialization
......@@ -1006,13 +973,14 @@ CMD <= f_cmd_to_string(CMD_INT);
BURST_LENGTH := (others => 512);
NEXT_CID := N_COMPLETION_ID - 1;
CURRENT_CID := N_COMPLETION_ID - 1;
DEBUG := 0;
CPL_POP_PTR := (others => 0);
CPL_CID := 0;
CPL_MODULO := 64;
INBOUND_READ_REQUEST_CPL_STATE <= (others => false);
loop
CMD_RD_DATA_OUT_VALID <= '0';
CMD_ACK <= '0';
wait on CMD_REQ, CLK;
......@@ -1037,7 +1005,6 @@ CMD <= f_cmd_to_string(CMD_INT);
wait until(CLK'event and (CLK = '1'));
end if;
CHAR_PTR := 1; -- Point to beginning of line
-- report "Q_CMD " & QCMD;
......@@ -1050,11 +1017,6 @@ CMD <= f_cmd_to_string(CMD_INT);
-- report "Command " & L_CMD;
if(not MODE_PRIMARY) then
DEBUG := DEBUG + 1;
end if;
--============================================================--
-- Command Decode --
--============================================================--
......@@ -1675,7 +1637,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
......@@ -2175,7 +2142,14 @@ writeline(OUT_FILE, OUTPUT_LINE);
OUT_VALID <= '1';
OUT_DFRAME <= '1';
wait until(CLK'event and (CLK = '1'));
-- Do not proceed if the FPGA is not ready
loop
wait until(CLK'event and (CLK = '1'));
if (P2L_RDY = '1') then
exit;
end if;
OUT_VALID <= '0';
end loop;
-- See if we want to insert random wait states
if(IWAIT_RANDOM > 0) then -- Insert wait states
......@@ -2224,7 +2198,16 @@ writeline(OUT_FILE, OUTPUT_LINE);
OUT_DFRAME <= '0';
end if;
wait until(CLK'event and (CLK = '1'));
OUT_VALID <= '1';
-- Do not proceed if the FPGA is not ready
loop
wait until(CLK'event and (CLK = '1'));
if (P2L_RDY = '1') then
exit;
end if;
OUT_VALID <= '0';
end loop;
CPL_POP_PTR(CPL_CID) := CPL_POP_PTR(CPL_CID) + 1;
......@@ -2263,7 +2246,7 @@ writeline(OUT_FILE, OUTPUT_LINE);
end if;
end loop;
end process;
end process p_out_fsm;
--#########################################################################--
--
......@@ -2272,7 +2255,7 @@ writeline(OUT_FILE, OUTPUT_LINE);
-- (Handles RX to the BFM: L2P for Primary and P2L for secondary)
--
--#########################################################################--
process
p_in_fsm: process
--file OUT_FILE : text is out "STD_OUTPUT";
file OUT_FILE : text open write_mode is "NullFile";
variable OUTPUT_LINE : line;
......@@ -2326,7 +2309,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'));
......@@ -2492,7 +2475,11 @@ writeline(OUT_FILE, OUTPUT_LINE);
if(CID_COUNT < N_INBOUND_RD_OUTSTANDING) then -- OK to accept the request
INBOUND_READ_REQUEST_ARRAY(COMPLETION_ID).ADDRESS <= HEADER_ADDR_HI & HEADER_ADDR_LOW;
INBOUND_READ_REQUEST_ARRAY(COMPLETION_ID).BAR_HIT <= to_mvl(BFM_BAR_HIT(1)) & to_mvl(BFM_BAR_HIT(0));
INBOUND_READ_REQUEST_ARRAY(COMPLETION_ID).LENGTH <= to_int(HEADER_LENGTH);
if to_int(HEADER_LENGTH) = 0 then
INBOUND_READ_REQUEST_ARRAY(COMPLETION_ID).LENGTH <= 1024;
else
INBOUND_READ_REQUEST_ARRAY(COMPLETION_ID).LENGTH <= to_int(HEADER_LENGTH);
end if;
INBOUND_READ_REQUEST_ARRAY(COMPLETION_ID).STATE <= not INBOUND_READ_REQUEST_ARRAY(COMPLETION_ID).STATE;
INBOUND_READ_REQUEST_ARRAY(COMPLETION_ID).TC <= HEADER_TC;
INBOUND_READ_REQUEST_ARRAY(COMPLETION_ID).V <= HEADER_V;
......@@ -2514,7 +2501,11 @@ writeline(OUT_FILE, OUTPUT_LINE);
--* Process the Read Completion
--*-------------------------------------------------------------
I_HEADER_LENGTH := to_int(HEADER_LENGTH);
if to_int(HEADER_LENGTH) = 0 then
I_HEADER_LENGTH := 1024;
else
I_HEADER_LENGTH := to_int(HEADER_LENGTH);
end if;
I_CID := to_int(HEADER_CID);
if(RD_BUFFER_PTR(I_CID) = 0) then -- start of a completion sequence
......@@ -2544,11 +2535,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));
......@@ -2606,8 +2597,19 @@ writeline(OUT_FILE, OUTPUT_LINE);
end loop;
end process;
end process p_in_fsm;
--#########################################################################--
--
-- 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;
--#########################################################################--
--
......@@ -2617,7 +2619,7 @@ writeline(OUT_FILE, OUTPUT_LINE);
--
--#########################################################################--
process
ram_handler: process
--file OUT_FILE : text is out "STD_OUTPUT";
-- file OUT_FILE : text open write_mode is "STD_OUTPUT";
-- variable OUTPUT_LINE : line;
......@@ -2685,26 +2687,6 @@ writeline(OUT_FILE, OUTPUT_LINE);
end loop;
end process;
--#########################################################################--
--
-- Random # generator
--
-- Uses PRBS-23
--
--#########################################################################--
process(CLK0o)
variable RNDOUT : integer;
variable SEED : integer;
begin
if(RSTOUTo = '1') then
SEED := 5000;
elsif(CLK0o'event and CLK0o = '1') then
get_random(SEED, 0, 100, RNDOUT);
RANDOM_NUMBER <= RNDOUT;
end if;
end process;
--#########################################################################--
--
-- L2P Bus Sniffer
......@@ -2716,7 +2698,7 @@ writeline(OUT_FILE, OUTPUT_LINE);
L2P_CLKi_90 <= transport L2P_CLKpi after (T_LCLKi/4);
end process;
process
l2p_sniffer: process
file OUT_FILE : text open write_mode is "NullFile";
variable OUTPUT_LINE : line;
variable vHEADER : std_ulogic_vector(31 downto 0);
......@@ -2724,116 +2706,121 @@ writeline(OUT_FILE, OUTPUT_LINE);
variable vTYPE : std_ulogic_vector(3 downto 0);
variable START : time;
begin
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '1') and (L2P_VALIDi = '1') and MODE_PRIMARY);
START := NOW;
if(L2P_DFRAMEi = '1') then
vHEADER(15 downto 0) := L2P_DATAi;
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '0'));
vHEADER(31 downto 16) := L2P_DATAi;
vTYPE := vHEADER(27 downto 24);
vADDRESS := (others => '0');
-- Upper Address
if((vTYPE = "0001") or (vTYPE = "0011")) then -- address is 64 bits
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '1') and (L2P_VALIDi = '1'));
vADDRESS(47 downto 32) := L2P_DATAi;
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '0'));
vADDRESS(63 downto 48) := L2P_DATAi;
end if;
-- Lower Address
if((vTYPE = "0000") or (vTYPE = "0001") or (vTYPE = "0010") or (vTYPE = "0011") or (vTYPE = "0100")) then -- address is required
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '1') and (L2P_VALIDi = '1'));
vADDRESS(15 downto 0) := L2P_DATAi;
if not MODE_PRIMARY then
wait;
end if;
wait until rising_edge(L2P_CLKi_90);
if L2P_VALIDi = '1' then
START := NOW;
if(L2P_DFRAMEi = '1') then
vHEADER(15 downto 0) := L2P_DATAi;
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '0'));
vADDRESS(31 downto 16) := L2P_DATAi;
end if;
vHEADER(31 downto 16) := L2P_DATAi;
vTYPE := vHEADER(27 downto 24);
vADDRESS := (others => '0');
-- Upper Address
if((vTYPE = "0001") or (vTYPE = "0011")) then -- address is 64 bits
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '1') and (L2P_VALIDi = '1'));
vADDRESS(47 downto 32) := L2P_DATAi;
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '0'));
vADDRESS(63 downto 48) := L2P_DATAi;
end if;
-- Lower Address
if((vTYPE = "0000") or (vTYPE = "0001") or (vTYPE = "0010") or (vTYPE = "0011") or (vTYPE = "0100")) then -- address is required
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '1') and (L2P_VALIDi = '1'));
vADDRESS(15 downto 0) := L2P_DATAi;
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '0'));
vADDRESS(31 downto 16) := L2P_DATAi;
end if;
-- write(OUTPUT_LINE, ("-->> L2P Packet: " & to_string(START)));
-- writeline(OUT_FILE, OUTPUT_LINE);
write(OUTPUT_LINE, string'("-->>>> L2P Header: "));
case vTYPE is
when "0000" | "0001" =>
write(OUTPUT_LINE, string'("(L2P Master Read Request)"));
write(OUTPUT_LINE, string'(", FBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(23 downto 20));
write(OUTPUT_LINE, string'(", LBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(19 downto 16));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
-- writeline(OUT_FILE, OUTPUT_LINE);
write(OUTPUT_LINE, string'("-->>>> Address: 0x"));
write_hex_vector(OUTPUT_LINE, vADDRESS);
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
-- write(OUTPUT_LINE, ("-->> L2P Packet: " & to_string(START)));
-- writeline(OUT_FILE, OUTPUT_LINE);
write(OUTPUT_LINE, string'("-->>>> L2P Header: "));
case vTYPE is
when "0000" | "0001" =>
write(OUTPUT_LINE, string'("(L2P Master Read Request)"));
write(OUTPUT_LINE, string'(", FBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(23 downto 20));
write(OUTPUT_LINE, string'(", LBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(19 downto 16));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
-- writeline(OUT_FILE, OUTPUT_LINE);
write(OUTPUT_LINE, string'("-->>>> Address: 0x"));
write_hex_vector(OUTPUT_LINE, vADDRESS);
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0010" | "0011" =>
write(OUTPUT_LINE, string'("(L2P Master Write)"));
write(OUTPUT_LINE, string'(", FBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(23 downto 20));
write(OUTPUT_LINE, string'(", LBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(19 downto 16));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
-- writeline(OUT_FILE, OUTPUT_LINE);
write(OUTPUT_LINE, string'("-->>>> Address: 0x"));
write_hex_vector(OUTPUT_LINE, vADDRESS);
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0010" | "0011" =>
write(OUTPUT_LINE, string'("(L2P Master Write)"));
write(OUTPUT_LINE, string'(", FBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(23 downto 20));
write(OUTPUT_LINE, string'(", LBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(19 downto 16));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
-- writeline(OUT_FILE, OUTPUT_LINE);
write(OUTPUT_LINE, string'("-->>>> Address: 0x"));
write_hex_vector(OUTPUT_LINE, vADDRESS);
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0100" =>
write(OUTPUT_LINE, string'("(L2P Target Read Completion Without Data)"));
write(OUTPUT_LINE, string'(", STAT="));
write_hex_vector(OUTPUT_LINE, vHEADER(17 downto 16));
write(OUTPUT_LINE, string'(", L=" & to_str(vHEADER(15))));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0100" =>
write(OUTPUT_LINE, string'("(L2P Target Read Completion Without Data)"));
write(OUTPUT_LINE, string'(", STAT="));
write_hex_vector(OUTPUT_LINE, vHEADER(17 downto 16));
write(OUTPUT_LINE, string'(", L=" & to_str(vHEADER(15))));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0101" =>
write(OUTPUT_LINE, string'("(L2P Target Read Completion With Data)"));
write(OUTPUT_LINE, string'(", STAT="));
write_hex_vector(OUTPUT_LINE, vHEADER(17 downto 16));
write(OUTPUT_LINE, string'(", L=" & to_str(vHEADER(15))));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0101" =>
write(OUTPUT_LINE, string'("(L2P Target Read Completion With Data)"));
write(OUTPUT_LINE, string'(", STAT="));
write_hex_vector(OUTPUT_LINE, vHEADER(17 downto 16));
write(OUTPUT_LINE, string'(", L=" & to_str(vHEADER(15))));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when others =>
write(OUTPUT_LINE, string'("(Undefined)"));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
assert false report "---- ERROR: Unsupported TYPE in L2P Header"
severity error;
end case;
when others =>
write(OUTPUT_LINE, string'("(Undefined)"));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
assert false report "---- ERROR: Unsupported TYPE in L2P Header"
severity error;
end case;
if(L2P_DFRAMEi = '1') then
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '1') and (L2P_VALIDi = '1') and (L2P_DFRAMEi = '0'));
end if;
if(L2P_DFRAMEi = '1') then
wait until(L2P_CLKi_90'event and (L2P_CLKi_90 = '1') and (L2P_VALIDi = '1') and (L2P_DFRAMEi = '0'));
end if;
else
write(OUTPUT_LINE, string'("-- ERROR: L2P Bus: P2L_VALID asserted without P2L_DFRAME @"));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
else
write(OUTPUT_LINE, string'("-- ERROR: L2P Bus: L2P_VALID asserted without P2L_DFRAME @"));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
end if;
end if;
end process;
......@@ -2842,7 +2829,7 @@ writeline(OUT_FILE, OUTPUT_LINE);
-- P2L Bus Sniffer
--
--#########################################################################--
process
p2l_sniffer: process
file OUT_FILE : text open write_mode is "NullFile";
variable OUTPUT_LINE : line;
variable vHEADER : std_ulogic_vector(31 downto 0);
......@@ -2850,115 +2837,116 @@ writeline(OUT_FILE, OUTPUT_LINE);
variable vTYPE : std_ulogic_vector(3 downto 0);
variable START : time;
begin
wait until(P2L_CLKpi'event and (P2L_CLKpi = '1') and (P2L_VALIDi = '1') and MODE_PRIMARY);
START := NOW;
if(P2L_DFRAMEi = '1') then
vHEADER(15 downto 0) := P2L_DATAi;
wait until(P2L_CLKpi'event and (P2L_CLKpi = '0'));
vHEADER(31 downto 16) := P2L_DATAi;
vTYPE := vHEADER(27 downto 24);
vADDRESS := (others => '0');
-- Upper Address
if((vTYPE = "0001") or (vTYPE = "0011")) then -- address is 64 bits
wait until(P2L_CLKpi'event and (P2L_CLKpi = '1') and (P2L_VALIDi = '1'));
vADDRESS(47 downto 32) := P2L_DATAi;
wait until(P2L_CLKpi'event and (P2L_CLKpi = '0'));
vADDRESS(63 downto 48) := P2L_DATAi;
end if;
-- Lower Address
if((vTYPE = "0000") or (vTYPE = "0001") or (vTYPE = "0010") or (vTYPE = "0011") or (vTYPE = "0100")) then -- address is required
wait until(P2L_CLKpi'event and (P2L_CLKpi = '1') and (P2L_VALIDi = '1'));
vADDRESS(15 downto 0) := P2L_DATAi;
if not MODE_PRIMARY then
wait;
end if;
wait until rising_edge(P2L_CLKpi);
if P2L_VALIDi = '1' then
START := NOW;
if(P2L_DFRAMEi = '1') then
vHEADER(15 downto 0) := P2L_DATAi;
wait until(P2L_CLKpi'event and (P2L_CLKpi = '0'));
vADDRESS(31 downto 16) := P2L_DATAi;
end if;
vHEADER(31 downto 16) := P2L_DATAi;
vTYPE := vHEADER(27 downto 24);
vADDRESS := (others => '0');
-- Upper Address
if((vTYPE = "0001") or (vTYPE = "0011")) then -- address is 64 bits
wait until(P2L_CLKpi'event and (P2L_CLKpi = '1') and (P2L_VALIDi = '1'));
vADDRESS(47 downto 32) := P2L_DATAi;
wait until(P2L_CLKpi'event and (P2L_CLKpi = '0'));
vADDRESS(63 downto 48) := P2L_DATAi;
end if;
-- Lower Address
if((vTYPE = "0000") or (vTYPE = "0001") or (vTYPE = "0010") or (vTYPE = "0011") or (vTYPE = "0100")) then -- address is required
wait until(P2L_CLKpi'event and (P2L_CLKpi = '1') and (P2L_VALIDi = '1'));
vADDRESS(15 downto 0) := P2L_DATAi;
wait until(P2L_CLKpi'event and (P2L_CLKpi = '0'));
vADDRESS(31 downto 16) := P2L_DATAi;
end if;
write(OUTPUT_LINE, string'("--<<<< P2L Header: "));
case vTYPE is
when "0000" | "0001" =>
write(OUTPUT_LINE, string'("(P2L Target Read Request)"));
write(OUTPUT_LINE, string'(", FBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(23 downto 20));
write(OUTPUT_LINE, string'(", LBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(19 downto 16));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'("--<<<< Address: 0x"));
write_hex_vector(OUTPUT_LINE, vADDRESS);
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
write(OUTPUT_LINE, string'("--<<<< P2L Header: "));
case vTYPE is
when "0000" | "0001" =>
write(OUTPUT_LINE, string'("(P2L Target Read Request)"));
write(OUTPUT_LINE, string'(", FBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(23 downto 20));
write(OUTPUT_LINE, string'(", LBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(19 downto 16));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'("--<<<< Address: 0x"));
write_hex_vector(OUTPUT_LINE, vADDRESS);
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0010" | "0011" =>
write(OUTPUT_LINE, string'("(P2L Target Write)"));
write(OUTPUT_LINE, string'(", FBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(23 downto 20));
write(OUTPUT_LINE, string'(", LBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(19 downto 16));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'("--<<<< Address: 0x"));
write_hex_vector(OUTPUT_LINE, vADDRESS);
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0010" | "0011" =>
write(OUTPUT_LINE, string'("(P2L Target Write)"));
write(OUTPUT_LINE, string'(", FBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(23 downto 20));
write(OUTPUT_LINE, string'(", LBE=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(19 downto 16));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'("--<<<< Address: 0x"));
write_hex_vector(OUTPUT_LINE, vADDRESS);
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0100" =>
write(OUTPUT_LINE, string'("(P2L Master Read Completion Without Data)"));
write(OUTPUT_LINE, string'(", STAT="));
write_hex_vector(OUTPUT_LINE, vHEADER(17 downto 16));
write(OUTPUT_LINE, string'(", L=" & to_str(vHEADER(15))));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0100" =>
write(OUTPUT_LINE, string'("(P2L Master Read Completion Without Data)"));
write(OUTPUT_LINE, string'(", STAT="));
write_hex_vector(OUTPUT_LINE, vHEADER(17 downto 16));
write(OUTPUT_LINE, string'(", L=" & to_str(vHEADER(15))));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0101" =>
write(OUTPUT_LINE, string'("(P2L Master Read Completion With Data)"));
write(OUTPUT_LINE, string'(", STAT="));
write_hex_vector(OUTPUT_LINE, vHEADER(17 downto 16));
write(OUTPUT_LINE, string'(", L=" & to_str(vHEADER(15))));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when "0101" =>
write(OUTPUT_LINE, string'("(P2L Master Read Completion With Data)"));
write(OUTPUT_LINE, string'(", STAT="));
write_hex_vector(OUTPUT_LINE, vHEADER(17 downto 16));
write(OUTPUT_LINE, string'(", L=" & to_str(vHEADER(15))));
write(OUTPUT_LINE, string'(", V=" & to_str(vHEADER(12))));
write(OUTPUT_LINE, string'(", CID="));
write_hex_vector(OUTPUT_LINE, vHEADER(11 downto 10));
write(OUTPUT_LINE, string'(", LENGTH=0x"));
write_hex_vector(OUTPUT_LINE, vHEADER(9 downto 0));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
when others =>
write(OUTPUT_LINE, string'("(Undefined)"));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
assert false report "---- ERROR: Unsupported TYPE in P2L Header"
severity error;
end case;
when others =>
write(OUTPUT_LINE, string'("(Undefined)"));
write(OUTPUT_LINE, string'(" @ "));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
assert false report "---- ERROR: Unsupported TYPE in P2L Header"
severity error;
end case;
if(P2L_DFRAMEi = '1') then
wait until(P2L_CLKpi'event and (P2L_CLKpi = '1') and (P2L_VALIDi = '1') and (P2L_DFRAMEi = '0'));
end if;
if(P2L_DFRAMEi = '1') then
wait until(P2L_CLKpi'event and (P2L_CLKpi = '1') and (P2L_VALIDi = '1') and (P2L_DFRAMEi = '0'));
end if;
else
write(OUTPUT_LINE, string'("-- ERROR: P2L Bus: P2L_VALID asserted without P2L_DFRAME @"));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
else
write(OUTPUT_LINE, string'("-- ERROR: P2L Bus: P2L_VALID asserted without P2L_DFRAME @"));
write(OUTPUT_LINE, START);
writeline(OUT_FILE, OUTPUT_LINE);
end if;
end if;
end process;
end MODEL;
......@@ -37,7 +37,7 @@ PACKAGE mem_model is
width : POSITIVE; -- # word length
length : POSITIVE; -- # of memory locations
row_data_ptr : row_data_ptr_type; -- ptr to memory ptrs.
default : default_ptr_type; -- ptr to default memory word value
default_val : default_ptr_type; -- ptr to default memory word value
end record;
type mem_id_type is access mem_id_rtype;
......@@ -64,6 +64,12 @@ PACKAGE mem_model is
--********************************************************************************
impure Function SRAM_Initialize ( Constant name : IN string;
Constant length : IN POSITIVE;
Constant width : IN POSITIVE;
Constant default_word : IN std_logic_vector
) return mem_id_type;
impure Function SRAM_Initialize_u ( Constant name : IN string;
Constant length : IN POSITIVE;
Constant width : IN POSITIVE;
Constant default_word : IN std_ulogic_vector
......@@ -946,9 +952,9 @@ end;
return nad;
end;
Function address_trans ( Constant mem_length : IN POSITIVE;
Constant addr : IN std_ulogic_vector
) return NATURAL is
Function address_trans_u ( Constant mem_length : IN POSITIVE;
Constant addr : IN std_ulogic_vector
) return NATURAL is
Variable nad, power : NATURAL;
Variable uonce : BOOLEAN := TRUE;
......@@ -995,9 +1001,9 @@ end;
return nad;
end;
Function address_trans ( Constant mem_length : IN POSITIVE;
Constant addr : IN bit_vector
) return NATURAL is
Function address_trans_b ( Constant mem_length : IN POSITIVE;
Constant addr : IN bit_vector
) return NATURAL is
Variable nad, power : NATURAL;
Variable vect_size : integer := vector_size(mem_length - 1);
......@@ -1068,7 +1074,7 @@ end;
ptr := mem_id.row_data_ptr(row).rowptr;
for i in 0 to mem_id.columns - 1 loop
for j in 0 to mem_id.width - 1 loop
ptr(i,j) := To_UX01(mem_id.default(j));
ptr(i,j) := To_UX01(mem_id.default_val(j));
end loop;
end loop;
end if;
......@@ -1198,7 +1204,7 @@ end;
width => width,
length => length,
row_data_ptr => NULL,
default => NULL
default_val => NULL
);
if ( (length mod SRAM_COL_SIZE) /= 0) then
......@@ -1230,7 +1236,7 @@ end;
end loop;
-- set default word
mem_id.default := new std_logic_vector(mem_id.width - 1 downto 0);
mem_id.default_val := new std_logic_vector(mem_id.width - 1 downto 0);
if (default_word'length /= mem_id.width) then
assert (default_word'length = 0)
......@@ -1239,18 +1245,18 @@ end;
& "default will be set to a word filled with 'U'"
severity ERROR;
for i in 0 to mem_id.width - 1 loop
mem_id.default(i) := 'U';
mem_id.default_val(i) := 'U';
end loop;
else
mem_id.default.all := To_X01(default_word);
mem_id.default_val.all := To_X01(default_word);
end if;
return mem_id;
end;
impure Function SRAM_Initialize ( Constant name : IN string;
impure Function SRAM_Initialize_u ( Constant name : IN string;
Constant length : IN POSITIVE;
Constant width : IN POSITIVE;
Constant default_word : IN std_ulogic_vector
......@@ -1493,13 +1499,13 @@ end;
end if;
-- if collumn not allocated & fill value is not the default or all x's then allocate
if ( (mem_id.row_data_ptr(row).rowptr = NULL) and (alias_reset /= mem_id.default.all)
if ( (mem_id.row_data_ptr(row).rowptr = NULL) and (alias_reset /= mem_id.default_val.all)
and (alias_reset /= xvector) ) then
allocate_row (mem_id, row);
-- if filling partial row with default and currently is Xs then allocate
elsif ( (mem_id.row_data_ptr(row).rowptr = NULL) and (alias_reset = mem_id.default.all)
elsif ( (mem_id.row_data_ptr(row).rowptr = NULL) and (alias_reset = mem_id.default_val.all)
and mem_id.row_data_ptr(row).all_xs and
( (rstart_col /= 0) or (rend_col /= mem_id.columns - 1)) ) then
......@@ -1512,7 +1518,7 @@ end;
end if;
-- if filling entire collumn with default then deallocate it
If ( (alias_reset = mem_id.default.all) and (rstart_col = 0) and
If ( (alias_reset = mem_id.default_val.all) and (rstart_col = 0) and
(rend_col = mem_id.columns - 1) ) then
if (mem_id.row_data_ptr(row).rowptr /= NULL) then
......@@ -1872,18 +1878,18 @@ end;
data := (others => 'X');
tdata := From_HexString1(word)(file_width - 1 downto 0);
data(rwidth - 1 downto 0) := bv_To_StdLogicvector(tdata(rwidth - 1 downto 0));
if mem_id.default = NULL then
if mem_id.default_val = NULL then
mem_id.default := new std_logic_vector(mem_id.width - 1 downto 0);
mem_id.default_val := new std_logic_vector(mem_id.width - 1 downto 0);
else
deallocate (mem_id.default);
deallocate (mem_id.default_val);
mem_id.default := new std_logic_vector(mem_id.width - 1 downto 0);
mem_id.default_val := new std_logic_vector(mem_id.width - 1 downto 0);
end if;
mem_id.default.all := data;
mem_id.default_val.all := data;
get_sym (word, str_buff, b_Index, file_error, in_file, line_num);
w_id := word_id(word);
......@@ -2173,7 +2179,7 @@ end;
mem_word := (others => 'X');
elsif (mem_id.row_data_ptr(row).rowptr = NULL) then -- if not allocated return default
mem_word := mem_id.default.all;
mem_word := mem_id.default_val.all;
else
short_ptr := mem_id.row_data_ptr(row).rowptr;
......@@ -2239,7 +2245,7 @@ end;
if (mem_id.row_data_ptr(row).all_xs) then
data := 'X';
elsif (mem_id.row_data_ptr(row).rowptr = NULL) then
data := mem_id.default(0);
data := mem_id.default_val(0);
else
--data := mem_id.row_data_ptr(row).rowptr(column,0);
-- *************************************
......@@ -2286,7 +2292,7 @@ end;
Variable temp : std_logic_vector(data'length - 1 downto 0);
begin
Mem_Basic_Read (temp, mem_id, address_trans(mem_id.length, address));
Mem_Basic_Read (temp, mem_id, address_trans_u(mem_id.length, address));
data := std_ulogic_vector (temp);
end;
......@@ -2312,7 +2318,7 @@ end;
begin
Mem_Basic_Write ( mem_id,
Address_trans(mem_id.length, address),
Address_trans_u(mem_id.length, address),
To_X01(std_logic_vector(data))
);
end;
......
files = ["dummy_ctrl_regs.vhd",
"dummy_stat_regs.vhd",
"wb_addr_decoder.vhd"]
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Dummy control registers
---------------------------------------------------------------------------------------
-- File : ../rtl/dummy_ctrl_regs.vhd
-- Author : auto-generated by wbgen2 from dummy_ctrl_regs_wb_slave.wb
-- Created : Fri May 13 11:28:38 2011
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE dummy_ctrl_regs_wb_slave.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dummy_ctrl_regs_wb_slave is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
-- Ports for PASS_THROUGH field: 'IRQ' in reg: 'DUMMY_1'
dummy_reg_1_o : out std_logic_vector(31 downto 0);
dummy_reg_1_wr_o : out std_logic;
-- Port for std_logic_vector field: 'Dummy register 2' in reg: 'DUMMY_2'
dummy_reg_2_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register 3' in reg: 'DUMMY_3'
dummy_reg_3_o : out std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register for LED control' in reg: 'DUMMY_LED'
dummy_reg_led_o : out std_logic_vector(31 downto 0)
);
end dummy_ctrl_regs_wb_slave;
architecture syn of dummy_ctrl_regs_wb_slave is
signal dummy_reg_2_int : std_logic_vector(31 downto 0);
signal dummy_reg_3_int : std_logic_vector(31 downto 0);
signal dummy_reg_led_int : std_logic_vector(31 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal bus_clock_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
dummy_reg_1_wr_o <= '0';
dummy_reg_2_int <= "00000000000000000000000000000000";
dummy_reg_3_int <= "00000000000000000000000000000000";
dummy_reg_led_int <= "00000000000000000000000000000000";
elsif rising_edge(bus_clock_int) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
dummy_reg_1_wr_o <= '0';
ack_in_progress <= '0';
else
dummy_reg_1_wr_o <= '0';
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
dummy_reg_1_wr_o <= '1';
else
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
dummy_reg_2_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= dummy_reg_2_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
dummy_reg_3_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= dummy_reg_3_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
dummy_reg_led_int <= wrdata_reg(31 downto 0);
else
rddata_reg(31 downto 0) <= dummy_reg_led_int;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_data_o <= rddata_reg;
-- IRQ
-- pass-through field: IRQ in register: DUMMY_1
dummy_reg_1_o <= wrdata_reg(31 downto 0);
-- Dummy register 2
dummy_reg_2_o <= dummy_reg_2_int;
-- Dummy register 3
dummy_reg_3_o <= dummy_reg_3_int;
-- Dummy register for LED control
dummy_reg_led_o <= dummy_reg_led_int;
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for Dummy status registers
---------------------------------------------------------------------------------------
-- File : ../../GN4124_core/hdl/gn4124core/design/rtl/dummy_stat_regs.vhd
-- Author : auto-generated by wbgen2 from ../../GN4124_core/hdl/gn4124core/design/wb_gen/dummy_stat_regs_wb_slave.wb
-- Created : Wed Nov 10 14:42:59 2010
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE ../../GN4124_core/hdl/gn4124core/design/wb_gen/dummy_stat_regs_wb_slave.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity dummy_stat_regs_wb_slave is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(1 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
-- Port for std_logic_vector field: 'Dummy register 1' in reg: 'DUMMY_1'
dummy_stat_reg_1_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register 2' in reg: 'DUMMY_2'
dummy_stat_reg_2_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register 3' in reg: 'DUMMY_3'
dummy_stat_reg_3_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Dummy register for switch status' in reg: 'DUMMY_SWITCH'
dummy_stat_reg_switch_i : in std_logic_vector(31 downto 0)
);
end dummy_stat_regs_wb_slave;
architecture syn of dummy_stat_regs_wb_slave is
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal bus_clock_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
elsif rising_edge(bus_clock_int) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
ack_in_progress <= '0';
else
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_1_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_2_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_3_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (wb_we_i = '1') then
else
rddata_reg(31 downto 0) <= dummy_stat_reg_switch_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_data_o <= rddata_reg;
-- Dummy register 1
-- Dummy register 2
-- Dummy register 3
-- Dummy register for switch status
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
--------------------------------------------------------------------------------
-- --
-- CERN BE-CO-HT GN4124 core for PCIe FMC carrier --
-- http://www.ohwr.org/projects/gn4124-core --
--------------------------------------------------------------------------------
--
-- unit name: wishbone address decoder
--
-- author: Matthieu Cattin (matthieu.cattin@cern.ch)
--
-- date: 02-08-2011
--
-- version: 0.1
--
-- description: Provides a simple wishbone address decoder.
-- Splits the memory windows into equal parts.
--
-- dependencies:
--
--------------------------------------------------------------------------------
-- GNU LESSER GENERAL PUBLIC LICENSE
--------------------------------------------------------------------------------
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source is distributed in the hope that it
-- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--------------------------------------------------------------------------------
-- last changes:
--------------------------------------------------------------------------------
-- TODO:
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use work.gn4124_core_pkg.all;
entity wb_addr_decoder is
generic
(
g_WINDOW_SIZE : integer := 18; -- Number of bits to address periph on the board (32-bit word address)
g_WB_SLAVES_NB : integer := 2
);
port
(
---------------------------------------------------------
-- GN4124 core clock and reset
clk_i : in std_logic;
rst_n_i : in std_logic;
---------------------------------------------------------
-- wishbone master interface
wbm_adr_i : in std_logic_vector(31 downto 0); -- Address
wbm_dat_i : in std_logic_vector(31 downto 0); -- Data out
wbm_sel_i : in std_logic_vector(3 downto 0); -- Byte select
wbm_stb_i : in std_logic; -- Strobe
wbm_we_i : in std_logic; -- Write
wbm_cyc_i : in std_logic; -- Cycle
wbm_dat_o : out std_logic_vector(31 downto 0); -- Data in
wbm_ack_o : out std_logic; -- Acknowledge
wbm_stall_o : out std_logic; -- Stall
---------------------------------------------------------
-- wishbone slaves interface
wb_adr_o : out std_logic_vector(31 downto 0); -- Address
wb_dat_o : out std_logic_vector(31 downto 0); -- Data out
wb_sel_o : out std_logic_vector(3 downto 0); -- Byte select
wb_stb_o : out std_logic; -- Strobe
wb_we_o : out std_logic; -- Write
wb_cyc_o : out std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Cycle
wb_dat_i : in std_logic_vector((32*g_WB_SLAVES_NB)-1 downto 0); -- Data in
wb_ack_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0); -- Acknowledge
wb_stall_i : in std_logic_vector(g_WB_SLAVES_NB-1 downto 0) -- Stall
);
end wb_addr_decoder;
architecture behaviour of wb_addr_decoder is
-----------------------------------------------------------------------------
-- Constants declaration
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Signals declaration
-----------------------------------------------------------------------------
-- Wishbone
signal s_wb_periph_addr : std_logic_vector(log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
signal wb_periph_addr : std_logic_vector(log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
signal s_wb_periph_select : std_logic_vector((2**s_wb_periph_addr'length)-1 downto 0);
signal s_wb_ack_muxed : std_logic;
signal wb_ack_t : std_logic;
signal s_wb_dat_i_muxed : std_logic_vector(31 downto 0);
signal s_wb_cyc_demuxed : std_logic_vector(g_WB_SLAVES_NB-1 downto 0);
signal wb_adr_t : std_logic_vector(g_WINDOW_SIZE-log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
begin
------------------------------------------------------------------------------
-- Wishbone master address decoding
------------------------------------------------------------------------------
-- Take the first N bits of the address to select the active wb peripheral
-- g_WINDOW_SIZE represents 32-bit word address window
s_wb_periph_addr <= wbm_adr_i(g_WINDOW_SIZE-1 downto g_WINDOW_SIZE-log2_ceil(g_WB_SLAVES_NB));
-----------------------------------------------------------------------------
-- One-hot decode function, s_wb_periph_select <= onehot_decode(s_wb_periph_addr);
-----------------------------------------------------------------------------
onehot_decode : process(s_wb_periph_addr)
variable v_onehot : std_logic_vector((2**s_wb_periph_addr'length)-1 downto 0);
variable v_index : integer range 0 to (2**s_wb_periph_addr'length)-1;
begin
v_onehot := (others => '0');
v_index := 0;
for i in s_wb_periph_addr'range loop
if (s_wb_periph_addr(i) = '1') then
v_index := 2*v_index+1;
else
v_index := 2*v_index;
end if;
end loop;
v_onehot(v_index) := '1';
s_wb_periph_select <= v_onehot;
end process onehot_decode;
-- Register multiplexed ack and data + periph address
p_wb_in_regs : process (clk_i, rst_n_i)
begin
if (rst_n_i = c_RST_ACTIVE) then
wb_periph_addr <= (others => '0');
wbm_dat_o <= (others => '0');
wb_ack_t <= '0';
elsif rising_edge(clk_i) then
wb_periph_addr <= s_wb_periph_addr;
wbm_dat_o <= s_wb_dat_i_muxed;
wb_ack_t <= s_wb_ack_muxed;
end if;
end process p_wb_in_regs;
wbm_ack_o <= wb_ack_t;
-- Select ack line of the active peripheral
p_ack_mux : process (wb_ack_i, wb_periph_addr)
begin
if (to_integer(unsigned(wb_periph_addr)) < g_WB_SLAVES_NB) then
s_wb_ack_muxed <= wb_ack_i(to_integer(unsigned(wb_periph_addr)));
else
s_wb_ack_muxed <= '0';
end if;
end process p_ack_mux;
-- Select stall line of the active peripheral
p_stall_mux : process (wb_stall_i, s_wb_periph_addr)
begin
if (to_integer(unsigned(s_wb_periph_addr)) < g_WB_SLAVES_NB) then
wbm_stall_o <= wb_stall_i(to_integer(unsigned(s_wb_periph_addr)));
else
wbm_stall_o <= '0';
end if;
end process p_stall_mux;
-- Select input data of the active peripheral
p_din_mux : process (wb_dat_i, wb_periph_addr)
begin
if (to_integer(unsigned(wb_periph_addr)) < g_WB_SLAVES_NB) then
s_wb_dat_i_muxed <=
wb_dat_i(31+(32*to_integer(unsigned(wb_periph_addr))) downto 32*to_integer(unsigned(wb_periph_addr)));
else
s_wb_dat_i_muxed <= (others => 'X');
end if;
end process p_din_mux;
-- Assert the cyc line of the selected peripheral
gen_cyc_demux : for i in 0 to g_WB_SLAVES_NB-1 generate
s_wb_cyc_demuxed(i) <= wbm_cyc_i and s_wb_periph_select(i) and not(wb_ack_t);
end generate gen_cyc_demux;
-- Slaves wishbone bus outputs
wb_dat_o <= wbm_dat_i;
wb_stb_o <= wbm_stb_i;
wb_we_o <= wbm_we_i;
wb_sel_o <= wbm_sel_i;
wb_cyc_o <= s_wb_cyc_demuxed;
-- extend address bus to 32-bit
wb_adr_t <= wbm_adr_i(g_WINDOW_SIZE-log2_ceil(g_WB_SLAVES_NB)-1 downto 0);
wb_adr_o(wb_adr_t'left downto 0) <= wb_adr_t;
wb_adr_o(31 downto wb_adr_t'left+1) <= (others => '0');
end behaviour;
peripheral {
name = "Dummy control registers";
description = "Wishbone slave for test of the CSR wishbone of the GN4124 core";
hdl_entity = "dummy_ctrl_regs_wb_slave";
prefix = "dummy_reg";
reg {
name = "DUMMY_1";
prefix = "1";
field {
name = "IRQ";
description = "Generates an IRQ";
type = PASS_THROUGH;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "DUMMY_2";
prefix = "2";
field {
name = "Dummy register 2";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "DUMMY_3";
prefix = "3";
field {
name = "Dummy register 3";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "DUMMY_LED";
prefix = "led";
field {
name = "Dummy register for LED control";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
};
peripheral {
name = "Dummy status registers";
description = "Wishbone slave for test of the CSR wishbone of the GN4124 core";
hdl_entity = "dummy_stat_regs_wb_slave";
prefix = "dummy_stat_reg";
reg {
name = "DUMMY_1";
prefix = "1";
field {
name = "Dummy register 1";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "DUMMY_2";
prefix = "2";
field {
name = "Dummy register 2";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "DUMMY_3";
prefix = "3";
field {
name = "Dummy register 3";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "DUMMY_SWITCH";
prefix = "switch";
field {
name = "Dummy register for switch status";
type = SLV;
size = 32;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
};
work/
Makefile
modelsim.ini
transcript*
vsim.wlf
usc.lst
action = "simulation"
sim_tool = "modelsim"
sim_top = "TB_SPEC"
target = "xilinx"
vcom_opt = "-93"
syn_device = "xc6slx45t"
syn_grade = "-3"
syn_package = "fgg484"
modules = {
"local" : [
"../top",
"../rtl",
"../../gn4124core/rtl",
"testbench",
],
"git" : [
"git://ohwr.org/hdl-core-lib/general-cores.git",
],
}
fetchto = "../../ip_cores"
//***********************************************************************************************
//***********************************************************************************************
//**
//** Name: cont_block_dma.c
//**
//** Description: DMA scenario for a 2MB contiguous block of memory.
//**
//**
//***********************************************************************************************
//***********************************************************************************************
//===============================================================================================
// This provides the framework for creating tests for the testbench as described in
// GN412x Simulation Test Bench User Guide
//===============================================================================================
#include "lib/maketest.c"
//===============================================================================================
// This provides the framework for creating microcode for the 3 or 4DW list type described in
// the application note: "Implementing Multi-channel DMA with the GN412x IP"
//===============================================================================================
#include "lib/vdma_service.c"
//===============================================================================================
// lambo.h contains the address map for the Lambo project
//===============================================================================================
#include "lambo.h"
//===============================================================================================
// Define the Memory Map
//===============================================================================================
#define BAR0_BASE 0xFF00000010000000ll
#define BAR1_BASE 0xFF000000A0000000ll
#define BFM_BAR0_BASE 0x87654321F0000000ll
#define BFM_BAR1_BASE 0xBB00000040000000ll
#define CHAN0_DESC_LIST_SIZE 3
#define L2P_CHAN0_SUB_DMA_LENGTH 0x1000
#define L2P_CHAN0_XFER_CTL 0x00010000
//===============================================================================================
// Define the SG List
//===============================================================================================
struct sg_entry_struct sg_list_chan0[] =
{
{ BFM_BAR0_BASE|0xFF1000C8, L2P_CHAN0_XFER_CTL | 0xF38, 1 },
{ BFM_BAR0_BASE|0xFF101000, L2P_CHAN0_XFER_CTL | (L2P_CHAN0_SUB_DMA_LENGTH & 0xFFF), 511 },
{ BFM_BAR0_BASE|0xFF300000, L2P_CHAN0_XFER_CTL | 0x0C8 | 0x80000000, 1 }, //Assert an interrupt
{ 0x0ll, 0, 0 }
};
//***********************************************************************************************
//**
//** vdma_main: This will insert the DMA microcode and data into the test script
//**
//** The last function call, vdma_process(), will cross reference all of the labels in the
//** source code so that you end up with the proper hexadecimal values that need to be written
//** to descriptor RAM.
//**
//***********************************************************************************************
void vdma_main()
{
vdma_org(0x0000); //This initializes the program address counter
data_address = 0x200; //This initializes the data space address counter
vdma_label("START");
vdma_nop(); //do nothing
//===============================================================================================
// START of the main program loop
//===============================================================================================
vdma_label("MAIN");
vdma_channel_service_4
(
"L2P_CHAN0", //label to be used for this specific channel
'l', //direction='l' for l2p or 'p' for p2l
0, //The event register bit to be used for interrupt generation
_EXT_COND_0, //External condition used for this channel
_EXT_COND_LO, //Set to either _EXT_COND_LO or _EXT_COND_HI
0, //set to non zero when the list will be updated dynamicaly
CHAN0_DESC_LIST_SIZE, //SYS_ADDR step size of list entries that have a repeat count
L2P_CHAN0_SUB_DMA_LENGTH, //Step size of list entries that have a repeat count
sg_list_chan0 //SG List itself
);
vdma_nop(); // This is not required (can be replaced with more channel servicing)
vdma_jmp(_ALWAYS, 0,"MAIN"); //loop forever
//===============================================================================================
// END of the main program loop
//===============================================================================================
//-----------------------------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------------------------
vdma_org(0x0100);
vdma_label("ZERO");
vdma_constant_n64(0); //The constant 0
vdma_label("MINUS1");
vdma_constant_n(0xFFFFFFFF); //The constant -1
vdma_label("THREE");
vdma_constant_n(3); //The constant 3
vdma_label("FOUR");
vdma_constant_n(4); //The constant 4
//===============================================================================================
// Must run vdma_process to resolve the cross-references and generate the microcode
//===============================================================================================
vdma_process(BAR0_BASE + 0x4000);
}
//***********************************************************************************************
//**
//** Main:
//**
//** Edit the program below to create your own test script.
//**
//***********************************************************************************************
main(argc,argv)
int argc;
char *argv[];
{
int offset=0, i;
//-----------------------------------------------------------------------------------------------
// Always call maketest_init at the beginning of a test program
//-----------------------------------------------------------------------------------------------
maketest_init(argc,argv);
//================================================================================================
//== START of user script
//================================================================================================
comment("-----------------------------------------------------------------------------");
comment("Generated from: simple.c - do not edit the vec file directly as it is not the source!");
comment("Short example of using the lambo TestBench");
comment("-----------------------------------------------------------------------------");
comment("Select the GN4124 Primary BFM");
model(0);
comment("Initialize the BFM to its default state");
init();
comment("\nDrive reset to the FPGA");
reset(16);
comment("\n");
comment("-----------------------------------------------------------------------------");
comment("Initialize the Primary GN412x BFM model");
comment("-----------------------------------------------------------------------------");
comment("These address ranges will generate traffic from the BFM to the FPGA");
comment("bar BAR ADDR SIZE VC TC S");
bar(0, BAR0_BASE, 0x20000000, 0, 7, 0);
bar(1, BAR1_BASE, 0x10000000, 1, 5, 0);
comment("\nThis allocates a RAM block inside the BFM for the FPGA to access");
comment("bfm_bar BAR ADDR SIZE");
bfm_bar(0, BFM_BAR0_BASE, 0x10000000);
bfm_bar(1, BFM_BAR1_BASE, 0x20000000);
comment("\nWait until the FPGA is un-reset and ready for traffic on the local bus");
wait(64);
comment("\n-------------------------------------------------------------------------------");
comment("DO some setup");
comment("-------------------------------------------------------------------------------");
comment("Lambo setup...");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(0x100);
wr(BAR0_BASE + DMA_SEQ_DPTR_REG, 0xF, 0x0);
wr(BAR0_BASE + DMA_SEQ_EVENT_EN_REG, 0xF, 0x3);
wr(BAR0_BASE + DMA_SEQ_EVENT_CLR_REG, 0xF, 0xFFFFFFFF);
wr(BAR0_BASE + APP_CFG, 0xF, 0x6);
wr(BAR0_BASE + APP_CFG, 0xF, 0x0);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x1F);
wr(BAR0_BASE + DMA_CFG, 0xF, 0x7);
wr(BAR0_BASE + APP_GEN_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_COUNT, 0xF, 0x0);
wr(BAR0_BASE + APP_RCV_ERR_COUNT, 0xF, 0x0);
wr(BAR0_BASE + DMA_PAYLOAD_SIZE, 0xF, 0x8020);
comment("\n-------------------------------------------------------------------------------");
comment("Setup the DMA microcode");
comment("-------------------------------------------------------------------------------");
vdma_main();
comment("\nStart VDMA");
wr(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x1);
comment("\n-------------------------------------------------------------------------------");
comment("Wait for an Interrupt for Channel 0");
comment("-------------------------------------------------------------------------------");
gpio_wait(8000, 0x0001, 0x0001);
comment("Clear the interrupt");
wr(BAR0_BASE + DMA_SEQ_EVENT_CLR_REG, 0xF, 0x00000001);
comment("\nRead VDMA idle status");
rd(BAR0_BASE + DMA_SEQ_CSR_REG, 0xF, 0x00000000, 0xFFFFFFFF);
flush(5000);
wait(16);
//================================================================================================
//== END of user script
//================================================================================================
fclose(outfp);
exit(0);
}
#define DMA_STATUS_MASK 0x0000
#define DMA_CFG 0x0004
#define DMA_SEQ_EVENT_SET_REG 0x0008
#define DMA_SEQ_EVENT_CLR_REG 0x000C
#define DMA_SEQ_EVENT_REG 0x0010
#define DMA_SEQ_EVENT_EN_REG 0x0014
#define DMA_SEQ_ADDR_LOW_REG 0x0018
#define DMA_SEQ_ADDR_HI_REG 0x001C
#define DMA_SEQ_DPTR_REG 0x0020
#define DMA_SEQ_XFER_CTRL_REG 0x0024
#define DMA_SEQ_RA_REG 0x0028
#define DMA_SEQ_RB_REG 0x002C
#define DMA_SEQ_CSR_REG 0x0030
#define DMA_PAYLOAD_SIZE 0x0034
#define DMA_STATUS 0x0038
#define DMA_STATUS_RAW 0x003C
#define APP_STATUS_MASK 0x0050
#define APP_CFG 0x0054
#define APP_GEN_COUNT 0x0058
#define APP_RCV_COUNT 0x005C
#define APP_RCV_ERR_COUNT 0x0060
#define APP_STATUS 0x0064
#define APP_STATUS_RAW 0x0068
#define DMA_SEQ_DESC_RAM 0x4000