URL
https://opencores.org/ocsvn/spi_slave/spi_slave/trunk
Subversion Repositories spi_slave
Compare Revisions
- This comparison shows the changes necessary to convert path
/spi_slave/trunk/bench/vhdl
- from Rev 34 to Rev 35
- ↔ Reverse comparison
Rev 34 → Rev 35
/opb_spi_slave_tb.vhd
0,0 → 1,805
------------------------------------------------------------------------------- |
-- Title : Testbench for design "opb_spi_slave" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : opb_spi_slave_tb.vhd |
-- Author : |
-- Company : |
-- Created : 2007-09-02 |
-- Last update: 2008-05-15 |
-- Platform : |
-- Standard : VHDL'87 |
------------------------------------------------------------------------------- |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2007 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 2007-09-02 1.0 d.koethe Created |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
use IEEE.numeric_std.all; -- conv_integer() |
|
library work; |
use work.opb_spi_slave_pack.all; |
------------------------------------------------------------------------------- |
|
entity opb_spi_slave_tb is |
generic ( |
-- 0: simple transfer 1 byte transmit/receive |
-- 1: transfer 4 bytes and check flags |
-- 2: write until TX-FIFO asserts full, read until RX-FIFO asserts full, read |
-- and compare data |
-- 3: check FIFO Reset form underflow condition |
-- 4: check FIFO Flags IRQ Generation |
-- 5: check Slave select IRQ Generation |
-- 6: test opb Master Transfer |
test : std_logic_vector(7 downto 0) := "01000000"); |
end opb_spi_slave_tb; |
|
------------------------------------------------------------------------------- |
|
architecture behavior of opb_spi_slave_tb is |
constant C_BASEADDR : std_logic_vector(0 to 31) := X"00000000"; |
constant C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFFFFFF"; |
constant C_USER_ID_CODE : integer := 0; |
constant C_OPB_AWIDTH : integer := 32; |
constant C_OPB_DWIDTH : integer := 32; |
constant C_FAMILY : string := "virtex-4"; |
-- |
-- constant C_SR_WIDTH : integer := 8; |
constant C_SR_WIDTH : integer := 32; |
-- |
constant C_MSB_FIRST : boolean := true; |
constant C_CPOL : integer range 0 to 1 := 0; |
constant C_PHA : integer range 0 to 1 := 0; |
constant C_FIFO_SIZE_WIDTH : integer range 4 to 7 := 7; |
constant C_DMA_EN : boolean := true; |
constant C_CRC_EN : boolean := true; |
|
component opb_spi_slave |
generic ( |
C_BASEADDR : std_logic_vector(0 to 31); |
C_HIGHADDR : std_logic_vector(0 to 31); |
C_USER_ID_CODE : integer; |
C_OPB_AWIDTH : integer; |
C_OPB_DWIDTH : integer; |
C_FAMILY : string; |
C_SR_WIDTH : integer; |
C_MSB_FIRST : boolean; |
C_CPOL : integer range 0 to 1; |
C_PHA : integer range 0 to 1; |
C_FIFO_SIZE_WIDTH : integer range 4 to 7; |
C_DMA_EN : boolean; |
C_CRC_EN : boolean); |
port ( |
OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH-1); |
OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
OPB_Clk : in std_logic; |
OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); |
OPB_RNW : in std_logic; |
OPB_Rst : in std_logic; |
OPB_select : in std_logic; |
OPB_seqAddr : in std_logic; |
Sln_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
Sln_errAck : out std_logic; |
Sln_retry : out std_logic; |
Sln_toutSup : out std_logic; |
Sln_xferAck : out std_logic; |
M_request : out std_logic; |
MOPB_MGrant : in std_logic; |
M_busLock : out std_logic; |
M_ABus : out std_logic_vector(0 to C_OPB_AWIDTH-1); |
M_BE : out std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
M_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
M_RNW : out std_logic; |
M_select : out std_logic; |
M_seqAddr : out std_logic; |
MOPB_errAck : in std_logic; |
MOPB_retry : in std_logic; |
MOPB_timeout : in std_logic; |
MOPB_xferAck : in std_logic; |
sclk : in std_logic; |
ss_n : in std_logic; |
mosi : in std_logic; |
miso_o : out std_logic; |
miso_i : in std_logic; |
miso_t : out std_logic; |
opb_irq : out std_logic); |
end component; |
|
signal OPB_ABus : std_logic_vector(0 to C_OPB_AWIDTH-1); |
signal OPB_BE : std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
signal OPB_Clk : std_logic; |
signal OPB_DBus : std_logic_vector(0 to C_OPB_DWIDTH-1); |
signal OPB_RNW : std_logic; |
signal OPB_Rst : std_logic; |
signal OPB_select : std_logic; |
signal OPB_seqAddr : std_logic; |
signal Sln_DBus : std_logic_vector(0 to C_OPB_DWIDTH-1); |
signal Sln_errAck : std_logic; |
signal Sln_retry : std_logic; |
signal Sln_toutSup : std_logic; |
signal Sln_xferAck : std_logic; |
signal M_request : std_logic; |
signal MOPB_MGrant : std_logic; |
signal M_busLock : std_logic; |
signal M_ABus : std_logic_vector(0 to C_OPB_AWIDTH-1); |
signal M_BE : std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
signal M_DBus : std_logic_vector(0 to C_OPB_DWIDTH-1); |
signal M_RNW : std_logic; |
signal M_select : std_logic; |
signal M_seqAddr : std_logic; |
signal MOPB_errAck : std_logic; |
signal MOPB_retry : std_logic; |
signal MOPB_timeout : std_logic; |
signal MOPB_xferAck : std_logic; |
signal sclk : std_logic; |
signal ss_n : std_logic; |
signal mosi : std_logic; |
signal miso_o : std_logic; |
signal miso_i : std_logic; |
signal miso_t : std_logic; |
signal opb_irq : std_logic; |
|
-- testbench |
constant clk_period : time := 10 ns; |
constant spi_clk_period : time := 50 ns; |
|
signal miso : std_logic; |
|
signal opb_read_data : std_logic_vector(31 downto 0); |
signal spi_value_in : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
signal OPB_Transfer_Abort : boolean; |
signal OPB_DBus0 : std_logic_vector(0 to C_OPB_DWIDTH-1); |
signal OPB_DBus1 : std_logic_vector(0 to C_OPB_DWIDTH-1); |
|
begin -- behavior |
|
-- component instantiation |
DUT : opb_spi_slave |
generic map ( |
C_BASEADDR => C_BASEADDR, |
C_HIGHADDR => C_HIGHADDR, |
C_USER_ID_CODE => C_USER_ID_CODE, |
C_OPB_AWIDTH => C_OPB_AWIDTH, |
C_OPB_DWIDTH => C_OPB_DWIDTH, |
C_FAMILY => C_FAMILY, |
C_SR_WIDTH => C_SR_WIDTH, |
C_MSB_FIRST => C_MSB_FIRST, |
C_CPOL => C_CPOL, |
C_PHA => C_PHA, |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, |
C_DMA_EN => C_DMA_EN, |
C_CRC_EN => C_CRC_EN) |
port map ( |
OPB_ABus => OPB_ABus, |
OPB_BE => OPB_BE, |
OPB_Clk => OPB_Clk, |
OPB_DBus => OPB_DBus, |
OPB_RNW => OPB_RNW, |
OPB_Rst => OPB_Rst, |
OPB_select => OPB_select, |
OPB_seqAddr => OPB_seqAddr, |
Sln_DBus => Sln_DBus, |
Sln_errAck => Sln_errAck, |
Sln_retry => Sln_retry, |
Sln_toutSup => Sln_toutSup, |
Sln_xferAck => Sln_xferAck, |
M_request => M_request, |
MOPB_MGrant => MOPB_MGrant, |
M_busLock => M_busLock, |
M_ABus => M_ABus, |
M_BE => M_BE, |
M_DBus => M_DBus, |
M_RNW => M_RNW, |
M_select => M_select, |
M_seqAddr => M_seqAddr, |
MOPB_errAck => MOPB_errAck, |
MOPB_retry => MOPB_retry, |
MOPB_timeout => MOPB_timeout, |
MOPB_xferAck => MOPB_xferAck, |
sclk => sclk, |
ss_n => ss_n, |
mosi => mosi, |
miso_o => miso_o, |
miso_i => miso_i, |
miso_t => miso_t, |
opb_irq => opb_irq); |
|
|
|
-- clock generation |
process |
begin |
OPB_Clk <= '0'; |
wait for clk_period; |
OPB_Clk <= '1'; |
wait for clk_period; |
end process; |
|
-- IOB-Buffer |
miso <= miso_o when (miso_t = '0') else |
'Z'; |
miso_i <= miso; |
|
-- OPB-Master arbiter/xferack generation |
process(OPB_Rst, OPB_Clk) |
begin |
if (OPB_Rst = '1') then |
MOPB_MGrant <= '0'; |
MOPB_xferAck <= '0'; |
MOPB_errAck <= '0'; |
elsif rising_edge(OPB_Clk) then |
-- arbiter |
if (M_request = '1') then |
MOPB_MGrant <= '1'; |
else |
MOPB_MGrant <= '0'; |
end if; |
|
-- xfer_Ack |
if (M_select = '1') then |
if (OPB_Transfer_Abort) then |
MOPB_errAck <= '1'; |
else |
if (conv_integer(M_ABus) >= 16#24000000#) then |
if (M_RNW = '1') then |
-- read |
OPB_DBus0(C_OPB_DWIDTH-C_SR_WIDTH to C_OPB_DWIDTH-1) <= "0000000000000000" & "00" & M_ABus(16 to C_OPB_DWIDTH-3); |
end if; |
MOPB_xferAck <= not MOPB_xferAck; |
end if; |
|
end if; |
|
|
else |
OPB_DBus0 <= (others => '0'); |
MOPB_errAck <= '0'; |
MOPB_xferAck <= '0'; |
end if; |
|
end if; |
end process; |
------------------------------------------------------------------------------- |
u1 : for i in 0 to 31 generate |
OPB_DBus(i) <= OPB_DBus0(i) or OPB_DBus1(i); |
end generate u1; |
|
------------------------------------------------------------------------------ |
-- waveform generation |
WaveGen_Proc : process |
variable temp : std_logic_vector(31 downto 0); |
variable first : std_logic_vector(7 downto 0) := (others => '0'); |
|
--------------------------------------------------------------------------- |
procedure opb_write ( |
constant adr : in std_logic_vector(7 downto 2); |
constant data : in integer) is |
begin |
-- write transmit data |
wait until rising_edge(OPB_Clk); |
OPB_ABus <= transport conv_std_logic_vector(conv_integer(adr & "00"), 32) after 2 ns; |
OPB_select <= transport '1' after 2 ns; |
OPB_RNW <= transport '0' after 2 ns; |
OPB_DBus1 <= transport conv_std_logic_vector(data, 32) after 2 ns; |
|
for i in 0 to 3 loop |
wait until rising_edge(OPB_Clk); |
if (Sln_xferAck = '1') then |
exit; |
end if; |
end loop; -- i |
OPB_DBus1 <= transport X"00000000" after 2 ns; |
OPB_ABus <= transport X"00000000" after 2 ns; |
OPB_select <= '0'; |
end procedure opb_write; |
------------------------------------------------------------------------------- |
procedure opb_read ( |
constant adr : in std_logic_vector(7 downto 2)) is |
begin |
wait until rising_edge(OPB_Clk); |
OPB_ABus <= transport conv_std_logic_vector(conv_integer(adr & "00"), 32) after 2 ns; |
OPB_select <= transport '1' after 2 ns; |
OPB_RNW <= transport '1' after 2 ns; |
OPB_DBus1 <= transport conv_std_logic_vector(0, 32) after 2 ns; |
|
for i in 0 to 3 loop |
wait until rising_edge(OPB_Clk); |
if (Sln_xferAck = '1') then |
opb_read_data <= Sln_DBus; |
exit; |
end if; |
end loop; -- i |
OPB_ABus <= transport X"00000000" after 2 ns; |
OPB_select <= transport '0' after 2 ns; |
wait until rising_edge(OPB_Clk); |
end procedure opb_read; |
------------------------------------------------------------------------------- |
procedure spi_transfer( |
constant spi_value_out : in std_logic_vector(C_SR_WIDTH-1 downto 0)) is |
begin |
-- CPHA=0 CPOL=0 C_MSB_FIRST=TRUE |
ss_n <= '0'; |
for i in C_SR_WIDTH-1 downto 0 loop |
mosi <= spi_value_out(i); |
wait for spi_clk_period/2; |
sclk <= '1'; |
spi_value_in(i) <= miso; |
wait for spi_clk_period/2; |
sclk <= '0'; |
end loop; -- i |
mosi <= 'Z'; |
wait for clk_period/2; |
ss_n <= '1'; |
wait for clk_period/2; |
end procedure spi_transfer; |
------------------------------------------------------------------------------- |
|
begin |
sclk <= '0'; |
ss_n <= '1'; |
mosi <= 'Z'; |
miso_i <= '0'; |
|
-- init OPB-Slave |
OPB_ABus <= (others => '0'); |
OPB_BE <= (others => '0'); |
OPB_RNW <= '0'; |
OPB_select <= '0'; |
OPB_seqAddr <= '0'; |
|
-- int opb_master |
MOPB_retry <= '0'; |
MOPB_timeout <= '0'; |
|
OPB_Transfer_Abort <= false; |
|
-- reset active |
OPB_Rst <= '1'; |
wait for 100 ns; |
-- reset inactive |
OPB_Rst <= '0'; |
|
|
for i in 0 to 7 loop |
wait until rising_edge(OPB_Clk); |
end loop; -- i |
|
-- write TX Threshold |
-- Bit [15:00] Prog Full Threshold |
-- Bit [31:16] Prog Empty Threshold |
opb_write(C_ADR_TX_THRESH, 16#0005000B#); |
|
-- write RX Threshold |
-- Bit [15:00] Prog Full Threshold |
-- Bit [31:16] Prog Empty Threshold |
opb_write(C_ADR_RX_THRESH, 16#0006000C#); |
|
|
--------------------------------------------------------------------------- |
-- simple transfer 1 byte transmit/receive |
if (test(0) = '1') then |
-- write transmit data |
opb_write(C_ADR_TX_DATA, 16#78#); |
|
-- enable GDE and TX_EN and RX_EN |
opb_write(C_ADR_CTL, 16#7#); |
|
-- send/receive 8bit |
spi_transfer(conv_std_logic_vector(16#B5#, C_SR_WIDTH)); |
|
-- compare transmit data |
assert (spi_value_in = conv_std_logic_vector(16#78#, C_SR_WIDTH)) report "Master Receive Failure" severity failure; |
|
-- read RX-Data Value |
opb_read(C_ADR_RX_DATA); |
|
-- compare receive data |
assert (opb_read_data = conv_std_logic_vector(16#B5#, C_SR_WIDTH)) report "Master Transfer Failure" severity failure; |
|
end if; |
--------------------------------------------------------------------------- |
-- transfer 4 bytes and check flags |
if (test(1) = '1') then |
opb_read(C_ADR_STATUS); |
-- only empty Bit and prog_empty set |
|
temp := (others => '0'); |
temp(SPI_SR_Bit_TX_Prog_empty) := '1'; |
temp(SPI_SR_Bit_TX_Empty) := '1'; |
temp(SPI_SR_Bit_RX_Prog_empty) := '1'; |
temp(SPI_SR_Bit_RX_Empty) := '1'; |
temp(SPI_SR_Bit_SS_n) := '1'; |
|
assert (opb_read_data = temp) report "Check Status Bits: TX: 0, RX: 0" severity failure; |
|
-- write transmit data |
opb_write(C_ADR_TX_DATA, 16#01#); |
|
|
opb_read(C_ADR_STATUS); |
temp := (others => '0'); |
temp(SPI_SR_Bit_TX_Prog_empty) := '1'; |
temp(SPI_SR_Bit_RX_Prog_empty) := '1'; |
temp(SPI_SR_Bit_RX_Empty) := '1'; |
temp(SPI_SR_Bit_SS_n) := '1'; |
|
assert (opb_read_data = temp) report "Check Status Bits: TX: 1, RX:0" severity failure; |
end if; |
--------------------------------------------------------------------------- |
-- write until TX-FIFO asserts full, read until RX-FIFO asserts full, read an |
-- compare data |
if (test(2) = '1') then |
for i in 2 to 255 loop |
opb_write(C_ADR_TX_DATA, i); |
opb_read(C_ADR_STATUS); |
-- check TX prog_empty deassert |
if ((opb_read_data(SPI_SR_Bit_TX_Prog_empty) = '0') and first(0) = '0') then |
assert (false) report "TX prog_emtpy deassert after " & integer'image(i) & " writes." severity warning; |
first(0) := '1'; |
end if; |
|
-- check TX prog_full assert |
if ((opb_read_data(SPI_SR_Bit_TX_Prog_Full) = '1') and first(1) = '0') then |
assert (false) report "TX prog_full assert after " & integer'image(i) & " writes." severity warning; |
first(1) := '1'; |
end if; |
|
-- check TX full assert |
if ((opb_read_data(SPI_SR_Bit_TX_Full) = '1') and first(2) = '0') then |
assert (false) report "TX full assert after " & integer'image(i) & " writes." severity warning; |
first(2) := '1'; |
exit; |
end if; |
|
end loop; -- i |
|
--------------------------------------------------------------------------- |
first := (others => '0'); |
|
-- 16 spi transfer |
for i in 1 to 255 loop |
spi_transfer(conv_std_logic_vector(i, C_SR_WIDTH)); |
opb_read(C_ADR_STATUS); |
|
------------------------------------------------------------------------- |
-- check TX FIFO flags |
-- check TX full deassert |
if ((opb_read_data(SPI_SR_Bit_TX_Full) = '0') and first(0) = '0') then |
assert (false) report "TX full deassert after " & integer'image(i) & " transfers." severity warning; |
first(0) := '1'; |
end if; |
|
-- check TX prog_full deassert |
if ((opb_read_data(SPI_SR_Bit_TX_Prog_Full) = '0') and first(1) = '0') then |
assert (false) report "TX prog_full deassert after " & integer'image(i) & " transfers." severity warning; |
first(1) := '1'; |
end if; |
|
-- check TX prog_emtpy assert |
if ((opb_read_data(SPI_SR_Bit_TX_Prog_empty) = '1') and first(2) = '0') then |
assert (false) report "TX prog_empty assert after " & integer'image(i) & " transfers." severity warning; |
first(2) := '1'; |
end if; |
|
-- check TX emtpy assert |
if ((opb_read_data(SPI_SR_Bit_TX_Empty) = '1') and first(3) = '0') then |
assert (false) report "TX empty assert after " & integer'image(i) & " transfers." severity warning; |
first(3) := '1'; |
end if; |
|
------------------------------------------------------------------------- |
-- check RX FIFO flags |
-- check RX empty deassert |
if ((opb_read_data(SPI_SR_Bit_RX_Empty) = '0') and first(4) = '0') then |
assert (false) report "RX empty deassert after " & integer'image(i) & " transfers." severity warning; |
first(4) := '1'; |
end if; |
|
-- check RX prog_empty deassert |
if ((opb_read_data(SPI_SR_Bit_RX_Prog_empty) = '0') and first(5) = '0') then |
assert (false) report "RX prog_empty deassert after " & integer'image(i) & " transfers." severity warning; |
first(5) := '1'; |
end if; |
|
-- check RX prog_full deassert |
if ((opb_read_data(SPI_SR_Bit_RX_Prog_Full) = '1') and first(6) = '0') then |
assert (false) report "RX prog_full assert after " & integer'image(i) & " transfers." severity warning; |
first(6) := '1'; |
end if; |
|
-- check RX full deassert |
if ((opb_read_data(SPI_SR_Bit_RX_Full) = '1') and first(7) = '0') then |
assert (false) report "RX full assert after " & integer'image(i) & " transfers." severity warning; |
first(7) := '1'; |
exit; |
end if; |
end loop; -- i |
|
|
--------------------------------------------------------------------------- |
-- read data from fifo |
first := (others => '0'); |
|
for i in 1 to 255 loop |
opb_read(C_ADR_RX_DATA); |
|
-- check data |
assert (i = conv_integer(opb_read_data)) report "Read data failure at " & integer'image(i) severity failure; |
|
opb_read(C_ADR_STATUS); |
-- check RX FIFO flags |
|
-- check RX full deassert |
if ((opb_read_data(SPI_SR_Bit_RX_Full) = '0') and first(0) = '0') then |
assert (false) report "RX full deassert after " & integer'image(i) & " transfers." severity warning; |
first(0) := '1'; |
end if; |
|
-- check RX prog_full deassert |
if ((opb_read_data(SPI_SR_Bit_RX_Prog_Full) = '0') and first(1) = '0') then |
assert (false) report "RX prog_full deassert after " & integer'image(i) & " transfers." severity warning; |
first(1) := '1'; |
end if; |
|
-- check RX prog_empty assert |
if ((opb_read_data(SPI_SR_Bit_RX_Prog_empty) = '1') and first(2) = '0') then |
assert (false) report "RX prog_empty assert after " & integer'image(i) & " transfers." severity warning; |
first(2) := '1'; |
end if; |
|
|
-- check RX empty assert |
if ((opb_read_data(SPI_SR_Bit_RX_Empty) = '1') and first(3) = '0') then |
assert (false) report "RX empty assert after " & integer'image(i) & " transfers." severity warning; |
first(3) := '1'; |
exit; |
end if; |
end loop; -- i |
end if; |
|
--------------------------------------------------------------------------- |
-- check FIFO Reset form underflow condition |
if (test(3) = '1') then |
-- add transfer to go in underflow condition |
spi_transfer(conv_std_logic_vector(0, C_SR_WIDTH)); |
|
-- reset core (Bit 4) |
opb_write(C_ADR_CTL, 16#F#); |
|
--Check flags |
temp := (others => '0'); |
temp(SPI_SR_Bit_TX_Prog_empty) := '1'; |
temp(SPI_SR_Bit_TX_Empty) := '1'; |
temp(SPI_SR_Bit_RX_Prog_empty) := '1'; |
temp(SPI_SR_Bit_RX_Empty) := '1'; |
temp(SPI_SR_Bit_SS_n) := '1'; |
|
assert (opb_read_data = temp) report "Status Bits after Reset failure" severity failure; |
end if; |
------------------------------------------------------------------------------- |
-- check FIFO Flags IRQ Generation |
if (test(4) = '1') then |
-- enable all IRQ except Chip select |
opb_write(C_ADR_IER, 16#3F#); |
-- global irq enable |
opb_write(C_ADR_DGIE, 16#1#); |
|
-- fill transmit buffer |
for i in 1 to 255 loop |
opb_write(C_ADR_TX_DATA, i); |
opb_read(C_ADR_STATUS); |
-- check TX full assert |
if ((opb_read_data(SPI_SR_Bit_TX_Full) = '1')) then |
assert (false) report "TX full assert after " & integer'image(i) & " writes." severity warning; |
exit; |
end if; |
end loop; -- i |
|
-- SPI-Data Transfers an Check TX Prog_Empty and TX Empty IRQ Generation |
for i in 1 to 255 loop |
spi_transfer(conv_std_logic_vector(0, C_SR_WIDTH)); |
wait until rising_edge(OPB_Clk); |
wait until rising_edge(OPB_Clk); |
wait until rising_edge(OPB_Clk); |
if (opb_irq = '1') then |
opb_read(C_ADR_ISR); |
-- TX Prog Empty |
if ((opb_read_data(SPI_ISR_Bit_TX_Prog_Empty) = '1')) then |
report "TX prog empty irq after " & integer'image(i) & " transfers."; |
-- clear_irq |
opb_write(C_ADR_ISR, 16#1#); |
wait until rising_edge(OPB_Clk); |
assert (opb_irq = '0') report "TX Prog Empty not cleared" severity warning; |
end if; |
|
-- TX EMPTY |
if ((opb_read_data(SPI_ISR_Bit_TX_Empty) = '1')) then |
report "TX empty irq after " & integer'image(i) & " transfers."; |
-- clear_irq |
opb_write(C_ADR_ISR, 16#2#); |
wait until rising_edge(OPB_Clk); |
assert (opb_irq = '0') report "IRQ TX Empty not cleared" severity warning; |
end if; |
|
-- TX Underflow |
if ((opb_read_data(SPI_ISR_Bit_TX_Underflow) = '1')) then |
report "TX underflow irq after " & integer'image(i) & " transfers."; |
-- clear_irq |
opb_write(C_ADR_ISR, 16#4#); |
wait until rising_edge(OPB_Clk); |
assert (opb_irq = '0') report "IRQ TX underflow not cleared" severity warning; |
end if; |
|
-- RX Prog Full |
if ((opb_read_data(SPI_ISR_Bit_RX_Prog_Full) = '1')) then |
report "RX prog full irq after " & integer'image(i) & " transfers."; |
-- clear_irq |
opb_write(C_ADR_ISR, 16#8#); |
wait until rising_edge(OPB_Clk); |
assert (opb_irq = '0') report "RX Prog Full not cleared" severity warning; |
end if; |
|
-- RX Full |
if ((opb_read_data(SPI_ISR_Bit_RX_Full) = '1')) then |
report "RX full irq after " & integer'image(i) & " transfers."; |
-- clear_irq |
opb_write(C_ADR_ISR, 16#10#); |
wait until rising_edge(OPB_Clk); |
assert (opb_irq = '0') report "RX Full not cleared" severity warning; |
end if; |
|
-- RX Overflow |
if ((opb_read_data(SPI_ISR_Bit_RX_Overflow) = '1')) then |
report "RX overflow irq after " & integer'image(i) & " transfers."; |
-- clear_irq |
opb_write(C_ADR_ISR, 2**SPI_ISR_Bit_RX_Overflow); |
wait until rising_edge(OPB_Clk); |
assert (opb_irq = '0') report "RX Overflow not cleared" severity warning; |
exit; |
end if; |
|
end if; |
|
end loop; -- i |
end if; |
--------------------------------------------------------------------------- |
-- check slave select irq |
if (test(5) = '1') then |
-- reset core |
opb_write(C_ADR_CTL, 16#F#); |
|
-- eable Chip select fall/rise IRQ |
opb_write(C_ADR_IER, 16#C0#); |
|
ss_n <= '0'; |
wait until rising_edge(OPB_Clk); |
wait until rising_edge(OPB_Clk); |
wait until rising_edge(OPB_Clk); |
if (opb_irq = '1') then |
opb_read(C_ADR_ISR); |
if ((opb_read_data(SPI_ISR_Bit_SS_Fall) = '1')) then |
report "SS Fall irq found"; |
-- clear_irq |
opb_write(C_ADR_ISR, 2**SPI_ISR_Bit_SS_Fall); |
wait until rising_edge(OPB_Clk); |
assert (opb_irq = '0') report "SS_Fall IRQ not cleared" severity warning; |
end if; |
end if; |
|
ss_n <= '1'; |
wait until rising_edge(OPB_Clk); |
wait until rising_edge(OPB_Clk); |
wait until rising_edge(OPB_Clk); |
if (opb_irq = '1') then |
opb_read(C_ADR_ISR); |
if ((opb_read_data(SPI_ISR_Bit_SS_Rise) = '1')) then |
report "SS Rise irq found"; |
-- clear_irq |
opb_write(C_ADR_ISR, 2**SPI_ISR_Bit_SS_Rise); |
wait until rising_edge(OPB_Clk); |
assert (opb_irq = '0') report "SS_Rise IRQ not cleared" severity warning; |
end if; |
end if; |
end if; |
------------------------------------------------------------------------------- |
-- test opb Master Transfer |
if (test(6) = '1') then |
|
-- enable SPI and CRC |
opb_write(C_ADR_CTL, 2**C_OPB_CTL_REG_DGE+2**C_OPB_CTL_REG_TX_EN+2**C_OPB_CTL_REG_RX_EN+2**C_OPB_CTL_REG_CRC_EN); |
-- write TX Threshold |
-- Bit [15:00] Prog Full Threshold |
-- Bit [31:16] Prog Empty Threshold |
opb_write(C_ADR_TX_THRESH, 16#0005000B#); |
|
-- write RX Threshold |
-- Bit [15:00] Prog Full Threshold |
-- Bit [31:16] Prog Empty Threshold |
|
-- Pog full must greater or equal than 16(Block Transfer Size)! |
opb_write(C_ADR_RX_THRESH, 16#0006000F#); |
|
-- set transmit buffer Base Adress |
opb_write(C_ADR_TX_DMA_ADDR, 16#24000000#); |
-- set block number |
opb_write(C_ADR_TX_DMA_NUM, 1); |
|
-- set RX-Buffer base adress |
opb_write(C_ADR_RX_DMA_ADDR, 16#25000000#); |
-- set block number |
opb_write(C_ADR_RX_DMA_NUM, 1); |
|
-- enable dma write transfer |
opb_write(C_ADR_RX_DMA_CTL, 1); |
|
-- enable dma read transfer |
opb_write(C_ADR_TX_DMA_CTL, 1); |
|
-- time to fill fifo from ram |
for i in 0 to 15 loop |
wait until rising_edge(OPB_Clk); |
end loop; -- i |
|
-- transfer 16 bytes |
-- data block |
for i in 0 to 15 loop |
spi_transfer(conv_std_logic_vector(i, C_SR_WIDTH)); |
assert (conv_integer(spi_value_in) = i) report "DMA Transfer 1 read data failure" severity failure; |
end loop; -- i |
|
-- crc_block |
for i in 16 to 31 loop |
spi_transfer(conv_std_logic_vector(i, C_SR_WIDTH)); |
if (i = 16) then |
assert (conv_integer(spi_value_in) = 16#e4ea78bf#) report "DMA-block CRC failure" severity failure; |
else |
assert (conv_integer(spi_value_in) = i) report "DMA Transfer 1 read data failure" severity failure; |
end if; |
end loop; -- i |
|
-- wait until RX transfer done |
for i in 0 to 15 loop |
opb_read(C_ADR_STATUS); |
if (opb_read_data(SPI_SR_Bit_RX_DMA_Done) = '1') then |
exit; |
end if; |
wait for 1 us; |
end loop; -- i |
|
-- check TX CRC Register |
opb_read(C_ADR_TX_CRC); |
assert (conv_integer(opb_read_data) = 16#e4ea78bf#) report "TX Register CRC Failure" severity failure; |
|
-- check RX CRC Register |
opb_read(C_ADR_RX_CRC); |
assert (conv_integer(opb_read_data) = 16#e4ea78bf#) report "RX Register CRC Failure" severity failure; |
|
wait for 1 us; |
end if; |
--------------------------------------------------------------------------- |
|
|
|
assert false report "Simulation sucessful" severity failure; |
end process WaveGen_Proc; |
|
|
|
end behavior; |
|
------------------------------------------------------------------------------- |
|
configuration opb_spi_slave_tb_behavior_cfg of opb_spi_slave_tb is |
for behavior |
end for; |
end opb_spi_slave_tb_behavior_cfg; |
|
------------------------------------------------------------------------------- |
/crc_core_tb.vhd
0,0 → 1,191
------------------------------------------------------------------------------- |
-- Title : Testbench for design "crc_core" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : crc_core_tb.vhd |
-- Author : |
-- Company : |
-- Created : 2008-03-23 |
-- Last update: 2008-03-23 |
-- Platform : |
-- Standard : VHDL'87 |
------------------------------------------------------------------------------- |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2008 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 2008-03-23 1.0 d.koethe Created |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
------------------------------------------------------------------------------- |
|
entity crc_core_tb is |
generic ( |
C_SR_WIDTH : integer := 32); |
|
end crc_core_tb; |
|
------------------------------------------------------------------------------- |
|
architecture behavior of crc_core_tb is |
component crc_core |
generic ( |
C_SR_WIDTH : integer); |
port ( |
rst : in std_logic; |
opb_clk : in std_logic; |
crc_en : in std_logic; |
crc_clr : in std_logic; |
opb_m_last_block : in std_logic; |
fifo_rx_en : in std_logic; |
fifo_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_rx_crc_value : out std_logic_vector(C_SR_WIDTH-1 downto 0); |
fifo_tx_en : in std_logic; |
fifo_tx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
tx_crc_insert : out std_logic; |
opb_tx_crc_value : out std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end component; |
|
signal rst : std_logic; |
signal opb_clk : std_logic; |
signal crc_en : std_logic; |
signal crc_clr : std_logic; |
signal opb_m_last_block : std_logic; |
signal fifo_rx_en : std_logic; |
signal fifo_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal opb_rx_crc_value : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal fifo_tx_en : std_logic; |
signal fifo_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal tx_crc_insert : std_logic; |
signal opb_tx_crc_value : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
constant C_CLK_PERIOD : time := 10 ns; |
|
begin -- behavior |
|
-- component instantiation |
DUT : crc_core |
generic map ( |
C_SR_WIDTH => C_SR_WIDTH) |
port map ( |
rst => rst, |
opb_clk => opb_clk, |
crc_en => crc_en, |
crc_clr => crc_clr, |
opb_m_last_block => opb_m_last_block, |
fifo_rx_en => fifo_rx_en, |
fifo_rx_data => fifo_rx_data, |
opb_rx_crc_value => opb_rx_crc_value, |
fifo_tx_en => fifo_tx_en, |
fifo_tx_data => fifo_tx_data, |
tx_crc_insert => tx_crc_insert, |
opb_tx_crc_value => opb_tx_crc_value); |
|
-- clock generation |
process |
begin |
opb_clk <= '0'; |
wait for C_CLK_PERIOD/2; |
opb_clk <= '1'; |
wait for C_CLK_PERIOD/2; |
end process; |
|
-- waveform generation |
WaveGen_Proc : process |
begin |
rst <= '1'; |
crc_en <= '0'; |
crc_clr <= '0'; |
opb_m_last_block <= '0'; |
fifo_rx_en <= '0'; |
fifo_rx_data <= (others => '0'); |
fifo_tx_en <= '0'; |
fifo_tx_data <= (others => '0'); |
wait for 100 ns; |
rst <= '0'; |
|
-- clear crc |
wait until rising_edge(opb_clk); |
crc_clr <= '1'; |
wait until rising_edge(opb_clk); |
crc_clr <= '0'; |
crc_en <= '1'; |
|
|
|
-- generate data block |
opb_m_last_block <= '0'; |
|
for i in 0 to 15 loop |
wait until rising_edge(opb_clk); |
-- RX |
fifo_rx_en <= '1'; |
fifo_rx_data <= conv_std_logic_vector(i, fifo_rx_data'length); |
-- TX |
fifo_tx_en <= '1'; |
fifo_tx_data <= conv_std_logic_vector(i, fifo_tx_data'length); |
end loop; -- i |
wait until rising_edge(opb_clk); |
fifo_rx_en <= '0'; |
fifo_rx_data <= (others => '0'); |
fifo_tx_en <= '0'; |
fifo_tx_data <= (others => '0'); |
wait until rising_edge(opb_clk); |
|
if (C_SR_WIDTH = 32) then |
assert (conv_integer(opb_rx_crc_value) = 16#eb99fa90#) report"RX_CRC_Failure" severity failure; |
assert (conv_integer(opb_tx_crc_value) = 16#eb99fa90#) report"RX_CRC_Failure" severity failure; |
end if; |
|
|
-- generate crc_block |
opb_m_last_block <= '1'; |
|
for i in 0 to 15 loop |
wait until rising_edge(opb_clk); |
-- RX |
fifo_rx_en <= '1'; |
fifo_rx_data <= (others => '1'); |
-- TX |
fifo_tx_en <= '1'; |
fifo_tx_data <= (others => '1'); |
end loop; -- i |
wait until rising_edge(opb_clk); |
fifo_rx_en <= '0'; |
fifo_rx_data <= (others => '0'); |
fifo_tx_en <= '0'; |
fifo_tx_data <= (others => '0'); |
wait until rising_edge(opb_clk); |
-- same value, no changes in last block |
if (C_SR_WIDTH = 32) then |
assert (conv_integer(opb_rx_crc_value) = 16#eb99fa90#) report"RX_CRC_Failure" severity failure; |
assert (conv_integer(opb_tx_crc_value) = 16#eb99fa90#) report"RX_CRC_Failure" severity failure; |
end if; |
opb_m_last_block <= '0'; |
|
|
wait for 100 ns; |
|
|
|
assert false report "Simulation Sucessful" severity failure; |
|
end process WaveGen_Proc; |
|
|
|
end behavior; |
|
------------------------------------------------------------------------------- |
|
configuration crc_core_tb_behavior_cfg of crc_core_tb is |
for behavior |
end for; |
end crc_core_tb_behavior_cfg; |
|
------------------------------------------------------------------------------- |
/opb_m_if_tb.vhd
0,0 → 1,313
------------------------------------------------------------------------------- |
-- Title : Testbench for design "opb_m_if" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : opb_m_if_tb.vhd |
-- Author : |
-- Company : |
-- Created : 2007-10-29 |
-- Last update: 2007-11-12 |
-- Platform : |
-- Standard : VHDL'87 |
------------------------------------------------------------------------------- |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2007 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 2007-10-29 1.0 d.koethe Created |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
use IEEE.numeric_std.all; -- conv_integer() |
------------------------------------------------------------------------------- |
|
entity opb_m_if_tb is |
|
end opb_m_if_tb; |
|
------------------------------------------------------------------------------- |
|
architecture behavior of opb_m_if_tb is |
|
component opb_m_if |
generic ( |
C_BASEADDR : std_logic_vector(0 to 31); |
C_HIGHADDR : std_logic_vector(0 to 31); |
C_USER_ID_CODE : integer; |
C_OPB_AWIDTH : integer; |
C_OPB_DWIDTH : integer; |
C_FAMILY : string; |
C_SR_WIDTH : integer; |
C_MSB_FIRST : boolean; |
C_CPOL : integer range 0 to 1; |
C_PHA : integer range 0 to 1; |
C_FIFO_SIZE_WIDTH : integer range 4 to 7); |
port ( |
OPB_Clk : in std_logic; |
OPB_Rst : in std_logic; |
OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); |
M_request : out std_logic; |
MOPB_MGrant : in std_logic; |
M_busLock : out std_logic; |
M_ABus : out std_logic_vector(0 to C_OPB_AWIDTH-1); |
M_BE : out std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
M_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
M_RNW : out std_logic; |
M_select : out std_logic; |
M_seqAddr : out std_logic; |
MOPB_errAck : in std_logic; |
MOPB_retry : in std_logic; |
MOPB_timeout : in std_logic; |
MOPB_xferAck : in std_logic; |
opb_m_tx_req : in std_logic; |
opb_m_tx_en : out std_logic; |
opb_m_tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_tx_dma_ctl : in std_logic_vector(0 downto 0); |
opb_tx_dma_addr : in std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_tx_dma_num : in std_logic_vector(15 downto 0); |
opb_tx_dma_done : out std_logic; |
opb_m_rx_req : in std_logic; |
opb_m_rx_en : out std_logic; |
opb_m_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_rx_dma_ctl : in std_logic_vector(0 downto 0); |
opb_rx_dma_addr : in std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_rx_dma_num : in std_logic_vector(15 downto 0); |
opb_rx_dma_done : out std_logic); |
end component; |
|
|
|
-- component generics |
constant C_BASEADDR : std_logic_vector(0 to 31) := X"00000000"; |
constant C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFFFFFF"; |
constant C_USER_ID_CODE : integer := 0; |
constant C_OPB_AWIDTH : integer := 32; |
constant C_OPB_DWIDTH : integer := 32; |
constant C_FAMILY : string := "virtex-4"; |
constant C_SR_WIDTH : integer := 8; |
constant C_MSB_FIRST : boolean := true; |
constant C_CPOL : integer range 0 to 1 := 0; |
constant C_PHA : integer range 0 to 1 := 0; |
constant C_FIFO_SIZE_WIDTH : integer range 4 to 7 := 7; |
|
-- component ports |
signal OPB_Clk : std_logic; |
signal OPB_Rst : std_logic; |
signal OPB_DBus : std_logic_vector(0 to C_OPB_DWIDTH-1); |
signal M_request : std_logic; |
signal MOPB_MGrant : std_logic; |
signal M_busLock : std_logic; |
signal M_ABus : std_logic_vector(0 to C_OPB_AWIDTH-1); |
signal M_BE : std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
signal M_DBus : std_logic_vector(0 to C_OPB_DWIDTH-1); |
signal M_RNW : std_logic; |
signal M_select : std_logic; |
signal M_seqAddr : std_logic; |
signal MOPB_errAck : std_logic; |
signal MOPB_retry : std_logic; |
signal MOPB_timeout : std_logic; |
signal MOPB_xferAck : std_logic; |
signal opb_m_tx_req : std_logic; |
signal opb_m_tx_en : std_logic; |
signal opb_m_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal opb_tx_dma_ctl : std_logic_vector(0 downto 0); |
signal opb_tx_dma_addr : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal opb_tx_dma_num : std_logic_vector(15 downto 0); |
signal opb_tx_dma_done : std_logic; |
signal opb_m_rx_req : std_logic; |
signal opb_m_rx_en : std_logic; |
signal opb_m_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal opb_rx_dma_ctl : std_logic_vector(0 downto 0); |
signal opb_rx_dma_addr : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal opb_rx_dma_num : std_logic_vector(15 downto 0); |
signal opb_rx_dma_done : std_logic; |
|
signal opb_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal opb_tx_data : std_logic_vector(0 to C_SR_WIDTH-1); |
|
begin -- behavior |
|
-- component instantiation |
opb_m_if_1: opb_m_if |
generic map ( |
C_BASEADDR => C_BASEADDR, |
C_HIGHADDR => C_HIGHADDR, |
C_USER_ID_CODE => C_USER_ID_CODE, |
C_OPB_AWIDTH => C_OPB_AWIDTH, |
C_OPB_DWIDTH => C_OPB_DWIDTH, |
C_FAMILY => C_FAMILY, |
C_SR_WIDTH => C_SR_WIDTH, |
C_MSB_FIRST => C_MSB_FIRST, |
C_CPOL => C_CPOL, |
C_PHA => C_PHA, |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH) |
port map ( |
OPB_Clk => OPB_Clk, |
OPB_Rst => OPB_Rst, |
OPB_DBus => OPB_DBus, |
M_request => M_request, |
MOPB_MGrant => MOPB_MGrant, |
M_busLock => M_busLock, |
M_ABus => M_ABus, |
M_BE => M_BE, |
M_DBus => M_DBus, |
M_RNW => M_RNW, |
M_select => M_select, |
M_seqAddr => M_seqAddr, |
MOPB_errAck => MOPB_errAck, |
MOPB_retry => MOPB_retry, |
MOPB_timeout => MOPB_timeout, |
MOPB_xferAck => MOPB_xferAck, |
opb_m_tx_req => opb_m_tx_req, |
opb_m_tx_en => opb_m_tx_en, |
opb_m_tx_data => opb_m_tx_data, |
opb_tx_dma_ctl => opb_tx_dma_ctl, |
opb_tx_dma_addr => opb_tx_dma_addr, |
opb_tx_dma_num => opb_tx_dma_num, |
opb_tx_dma_done => opb_tx_dma_done, |
opb_m_rx_req => opb_m_rx_req, |
opb_m_rx_en => opb_m_rx_en, |
opb_m_rx_data => opb_m_rx_data, |
opb_rx_dma_ctl => opb_rx_dma_ctl, |
opb_rx_dma_addr => opb_rx_dma_addr, |
opb_rx_dma_num => opb_rx_dma_num, |
opb_rx_dma_done => opb_rx_dma_done); |
|
|
-- clock generation |
process |
begin |
OPB_Clk <= '0'; |
wait for 10 ns; |
OPB_Clk <= '1'; |
wait for 10 ns; |
end process; |
|
|
-- arbiter/xferack |
process(OPB_Rst, OPB_Clk) |
begin |
if (OPB_Rst = '1') then |
MOPB_MGrant <= '0'; |
MOPB_xferAck <= '0'; |
opb_tx_data <= (others => '0'); |
elsif rising_edge(OPB_Clk) then |
-- arbiter |
if (M_request = '1') then |
MOPB_MGrant <= '1'; |
else |
MOPB_MGrant <= '0'; |
end if; |
|
-- xfer_Ack |
if (M_select = '1') then |
if (M_RNW = '1' and MOPB_xferAck = '1') then |
opb_tx_data <= opb_tx_data+1; |
end if; |
MOPB_xferAck <= not MOPB_xferAck; |
else |
opb_tx_data <= (others => '0'); |
MOPB_xferAck <= '0'; |
end if; |
end if; |
end process; |
|
OPB_DBus( 0 to C_OPB_DWIDTH-C_SR_WIDTH-1) <= (others => '0'); |
OPB_DBus(C_OPB_DWIDTH-C_SR_WIDTH to C_OPB_DWIDTH-1) <= opb_tx_data; |
|
-- rx fifo emulation |
process(OPB_Rst, OPB_Clk) |
begin |
if (OPB_Rst = '1') then |
opb_rx_data <= (others => '0'); |
elsif rising_edge(OPB_Clk) then |
if (opb_m_rx_en = '1') then |
opb_rx_data <= opb_rx_data+1; |
end if; |
end if; |
end process; |
|
opb_m_rx_data <= opb_rx_data; |
|
|
-- waveform generation |
WaveGen_Proc : process |
begin |
-- reset active |
OPB_Rst <= '1'; |
|
MOPB_errAck <= '0'; |
MOPB_retry <= '0'; |
MOPB_timeout <= '0'; |
|
opb_m_tx_req <= '0'; |
opb_tx_dma_ctl <= (others => '0'); |
opb_tx_dma_addr <= (others => '0'); |
opb_m_rx_req <= '0'; |
opb_rx_dma_ctl <= (others => '0'); |
opb_rx_dma_addr <= (others => '0'); |
|
|
|
|
wait for 100 ns; |
-- remove rst |
OPB_Rst <= '0'; |
--------------------------------------------------------------------------- |
-- write transfer |
opb_tx_dma_addr <= conv_std_logic_vector(16#24000000#, 32); |
|
wait until rising_edge(OPB_Clk); |
opb_tx_dma_ctl(0) <= '1'; |
|
|
wait until rising_edge(OPB_Clk); |
opb_m_tx_req <= '1'; -- asssert almost full flag |
wait until rising_edge(OPB_Clk); |
opb_m_tx_req <= '0'; -- deassert almost full flag |
|
wait for 1 us; |
|
--------------------------------------------------------------------------- |
-- read transfer |
opb_rx_dma_addr <= conv_std_logic_vector(16#25000000#, 32); |
|
wait until rising_edge(OPB_Clk); |
opb_rx_dma_ctl(0) <= '1'; |
|
-- first transfer |
wait until rising_edge(OPB_Clk); |
opb_m_rx_req <= '1'; -- asssert almost full flag |
wait until rising_edge(OPB_Clk); |
opb_m_rx_req <= '0'; -- deassert almost full flag |
wait for 1 us; |
|
-- second transfer |
wait until rising_edge(OPB_Clk); |
opb_m_rx_req <= '1'; -- asssert almost full flag |
wait until rising_edge(OPB_Clk); |
opb_m_rx_req <= '0'; -- deassert almost full flag |
wait for 1 us; |
--------------------------------------------------------------------------- |
|
|
assert false report "Simulation Sucessful" severity failure; |
|
end process WaveGen_Proc; |
|
|
|
end behavior; |
|
------------------------------------------------------------------------------- |
|
configuration opb_m_if_tb_behavior_cfg of opb_m_if_tb is |
for behavior |
end for; |
end opb_m_if_tb_behavior_cfg; |
|
------------------------------------------------------------------------------- |
/images-body.vhd
0,0 → 1,200
-------------------------------------------------------------------------- |
-- |
-- Copyright (C) 1993, Peter J. Ashenden |
-- Mail: Dept. Computer Science |
-- University of Adelaide, SA 5005, Australia |
-- e-mail: petera@cs.adelaide.edu.au |
-- |
-- This program is free software; you can redistribute it and/or modify |
-- it under the terms of the GNU General Public License as published by |
-- the Free Software Foundation; either version 1, or (at your option) |
-- any later version. |
-- |
-- This program 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 General Public License for more details. |
-- |
-- You should have received a copy of the GNU General Public License |
-- along with this program; if not, write to the Free Software |
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
-- |
-------------------------------------------------------------------------- |
-- |
-- $RCSfile: images-body.vhd,v $ $Revision: 1.1 $ $Date: 2007-11-30 20:22:01 $ |
-- |
-------------------------------------------------------------------------- |
-- |
-- Images package body. |
-- |
-- Functions that return the string image of values. |
-- Each image is a correctly formed literal according to the |
-- rules of VHDL-93. |
-- |
-------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
|
package images is |
function image ( |
constant bv : std_logic_vector) |
return string; |
end images; |
|
package body images is |
|
|
-- Image of bit vector as binary bit string literal |
-- (in the format B"...") |
-- Length of result is bv'length + 3 |
|
function image (bv : in bit_vector) return string is |
|
alias bv_norm : bit_vector(1 to bv'length) is bv; |
variable result : string(1 to bv'length + 3); |
|
begin |
result(1) := 'B'; |
result(2) := '"'; |
for index in bv_norm'range loop |
if bv_norm(index) = '0' then |
result(index + 2) := '0'; |
else |
result(index + 2) := '1'; |
end if; |
end loop; |
result(bv'length + 3) := '"'; |
return result; |
end image; |
------------------------------------------------------------------------------- |
-- Image of bit vector as binary bit string literal |
-- (in the format B"...") |
-- Length of result is bv'length + 3 |
|
function image (bv : in std_logic_vector) return string is |
|
alias bv_norm : std_logic_vector(1 to bv'length) is bv; |
variable result : string(1 to bv'length + 3); |
|
begin |
result(1) := 'B'; |
result(2) := '"'; |
for index in bv_norm'range loop |
if bv_norm(index) = '0' then |
result(index + 2) := '0'; |
else |
result(index + 2) := '1'; |
end if; |
end loop; |
result(bv'length + 3) := '"'; |
return result; |
end image; |
|
|
|
---------------------------------------------------------------- |
|
-- Image of bit vector as octal bit string literal |
-- (in the format O"...") |
-- Length of result is (bv'length+2)/3 + 3 |
|
function image_octal (bv : in bit_vector) return string is |
|
constant nr_digits : natural := (bv'length + 2) / 3; |
variable result : string(1 to nr_digits + 3); |
variable bits : bit_vector(0 to 3*nr_digits - 1) := (others => '0'); |
variable three_bits : bit_vector(0 to 2); |
variable digit : character; |
|
begin |
result(1) := 'O'; |
result(2) := '"'; |
bits(bits'right - bv'length + 1 to bits'right) := bv; |
for index in 0 to nr_digits - 1 loop |
three_bits := bits(3*index to 3*index + 2); |
case three_bits is |
when b"000" => |
digit := '0'; |
when b"001" => |
digit := '1'; |
when b"010" => |
digit := '2'; |
when b"011" => |
digit := '3'; |
when b"100" => |
digit := '4'; |
when b"101" => |
digit := '5'; |
when b"110" => |
digit := '6'; |
when b"111" => |
digit := '7'; |
end case; |
result(index + 3) := digit; |
end loop; |
result(nr_digits + 3) := '"'; |
return result; |
end image_octal; |
|
---------------------------------------------------------------- |
|
-- Image of bit vector as hex bit string literal |
-- (in the format X"...") |
-- Length of result is (bv'length+3)/4 + 3 |
|
function image_hex (bv : in bit_vector) return string is |
|
constant nr_digits : natural := (bv'length + 3) / 4; |
variable result : string(1 to nr_digits + 3); |
variable bits : bit_vector(0 to 4*nr_digits - 1) := (others => '0'); |
variable four_bits : bit_vector(0 to 3); |
variable digit : character; |
|
begin |
result(1) := 'X'; |
result(2) := '"'; |
bits(bits'right - bv'length + 1 to bits'right) := bv; |
for index in 0 to nr_digits - 1 loop |
four_bits := bits(4*index to 4*index + 3); |
case four_bits is |
when b"0000" => |
digit := '0'; |
when b"0001" => |
digit := '1'; |
when b"0010" => |
digit := '2'; |
when b"0011" => |
digit := '3'; |
when b"0100" => |
digit := '4'; |
when b"0101" => |
digit := '5'; |
when b"0110" => |
digit := '6'; |
when b"0111" => |
digit := '7'; |
when b"1000" => |
digit := '8'; |
when b"1001" => |
digit := '9'; |
when b"1010" => |
digit := 'A'; |
when b"1011" => |
digit := 'B'; |
when b"1100" => |
digit := 'C'; |
when b"1101" => |
digit := 'D'; |
when b"1110" => |
digit := 'E'; |
when b"1111" => |
digit := 'F'; |
end case; |
result(index + 3) := digit; |
end loop; |
result(nr_digits + 3) := '"'; |
return result; |
end image_hex; |
|
|
end images; |
/bin2gray_tb.vhd
0,0 → 1,118
------------------------------------------------------------------------------- |
-- Title : Testbench for design "bin2grey" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : bin2gray_tb.vhd |
-- Author : |
-- Company : |
-- Created : 2007-10-22 |
-- Last update: 2007-10-22 |
-- Platform : |
-- Standard : VHDL'87 |
------------------------------------------------------------------------------- |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2007 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 2007-10-22 1.0 d.koethe Created |
------------------------------------------------------------------------------- |
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use ieee.std_logic_arith.all; |
------------------------------------------------------------------------------- |
|
entity bin2gray_tb is |
|
end bin2gray_tb; |
|
------------------------------------------------------------------------------- |
|
architecture behavior of bin2gray_tb is |
|
component gray2bin |
generic ( |
width : integer); |
port ( |
in_gray : in std_logic_vector(width-1 downto 0); |
out_bin : out std_logic_vector(width-1 downto 0)); |
end component; |
|
component bin2gray |
generic ( |
width : integer); |
port ( |
in_bin : in std_logic_vector(width-1 downto 0); |
out_gray : out std_logic_vector(width-1 downto 0)); |
end component; |
|
component gray_adder |
generic ( |
width : integer); |
port ( |
in_gray : in std_logic_vector(width-1 downto 0); |
out_gray : out std_logic_vector(width-1 downto 0)); |
end component; |
|
-- component generics |
constant width : integer := 4; |
|
-- component ports |
signal in_bin : std_logic_vector(width-1 downto 0); |
signal out_gray : std_logic_vector(width-1 downto 0); |
signal out_bin : std_logic_vector(width-1 downto 0); |
signal out_gray_add_one : std_logic_vector(width-1 downto 0); |
|
begin -- behavior |
|
-- component instantiation |
bin2gray_1 : bin2gray |
generic map ( |
width => width) |
port map ( |
in_bin => in_bin, |
out_gray => out_gray); |
|
|
gray2bin_1 : gray2bin |
generic map ( |
width => width) |
port map ( |
in_gray => out_gray, |
out_bin => out_bin); |
|
|
gray_adder_1 : gray_adder |
generic map ( |
width => width) |
port map ( |
in_gray => out_gray, |
out_gray => out_gray_add_one); |
|
|
-- waveform generation |
WaveGen_Proc : process |
begin |
for i in 0 to 2**width-1 loop |
in_bin <= conv_std_logic_vector(i, width); |
wait for 10 ns; |
|
end loop; -- i |
assert false report "Simulation Sucessful" severity failure; |
|
end process WaveGen_Proc; |
|
|
|
end behavior; |
|
------------------------------------------------------------------------------- |
|
configuration bin2gray_tb_behavior_cfg of bin2gray_tb is |
for behavior |
end for; |
end bin2gray_tb_behavior_cfg; |
|
------------------------------------------------------------------------------- |
/rx_fifo_emu.vhd
0,0 → 1,37
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
|
entity rx_fifo_emu is |
|
generic ( |
C_SR_WIDTH : integer; |
C_RX_CMP_VALUE : integer); |
|
port ( |
rst : in std_logic; |
rx_clk : in std_logic; |
rx_en : in std_logic; |
rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0)); |
|
end rx_fifo_emu; |
|
|
architecture behavior of rx_fifo_emu is |
|
signal rx_data_cmp : std_logic_vector(C_SR_WIDTH-1 downto 0) := conv_std_logic_vector(C_RX_CMP_VALUE,C_SR_WIDTH); |
|
begin -- behavior |
process(rst, rx_clk) |
begin |
if (rst = '1') then |
elsif rising_edge(rx_clk) then |
if (rx_en = '1') then |
assert (rx_data = rx_data_cmp) report "RX-FIFO Compare Error" severity warning; |
rx_data_cmp <= rx_data_cmp+1; |
end if; |
end if; |
end process; |
end behavior; |
/opb_if_tb.vhd
0,0 → 1,252
------------------------------------------------------------------------------- |
-- Title : Testbench for design "opb_if" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : opb_if_tb.vhd |
-- Author : |
-- Company : |
-- Created : 2007-09-01 |
-- Last update: 2007-11-12 |
-- Platform : |
-- Standard : VHDL'87 |
------------------------------------------------------------------------------- |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2007 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 2007-09-01 1.0 d.koethe Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
library work; |
use work.opb_spi_slave_pack.all; |
|
------------------------------------------------------------------------------- |
|
entity opb_if_tb is |
|
end opb_if_tb; |
|
------------------------------------------------------------------------------- |
|
architecture behavior of opb_if_tb is |
|
component opb_if |
generic ( |
C_BASEADDR : std_logic_vector(0 to 31); |
C_HIGHADDR : std_logic_vector(0 to 31); |
C_USER_ID_CODE : integer; |
C_OPB_AWIDTH : integer; |
C_OPB_DWIDTH : integer; |
C_FAMILY : string; |
C_SR_WIDTH : integer; |
C_FIFO_SIZE_WIDTH : integer; |
C_DMA_EN : boolean); |
port ( |
OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH-1); |
OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
OPB_Clk : in std_logic; |
OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); |
OPB_RNW : in std_logic; |
OPB_Rst : in std_logic; |
OPB_select : in std_logic; |
OPB_seqAddr : in std_logic; |
Sln_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); |
Sln_errAck : out std_logic; |
Sln_retry : out std_logic; |
Sln_toutSup : out std_logic; |
Sln_xferAck : out std_logic; |
opb_s_tx_en : out std_logic; |
opb_s_tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_s_rx_en : out std_logic; |
opb_s_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
opb_ctl_reg : out std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); |
tx_thresh : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
rx_thresh : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
opb_fifo_flg : in std_logic_vector(C_NUM_FLG-1 downto 0); |
opb_dgie : out std_logic; |
opb_ier : out std_logic_vector(C_NUM_INT-1 downto 0); |
opb_isr : in std_logic_vector(C_NUM_INT-1 downto 0); |
opb_isr_clr : out std_logic_vector(C_NUM_INT-1 downto 0); |
opb_tx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_tx_dma_ctl : out std_logic_vector(0 downto 0); |
opb_tx_dma_num : out std_logic_vector(15 downto 0); |
opb_rx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
opb_rx_dma_ctl : out std_logic_vector(0 downto 0); |
opb_rx_dma_num : out std_logic_vector(15 downto 0)); |
end component; |
|
constant C_BASEADDR : std_logic_vector(0 to 31) := X"00000000"; |
constant C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFFFFFF"; |
constant C_USER_ID_CODE : integer := 3; |
constant C_OPB_AWIDTH : integer := 32; |
constant C_OPB_DWIDTH : integer := 32; |
constant C_FAMILY : string := "virtex-4"; |
constant C_SR_WIDTH : integer := 8; |
constant C_FIFO_SIZE_WIDTH : integer := 4; |
constant C_DMA_EN : boolean := true; |
|
|
signal OPB_ABus : std_logic_vector(0 to C_OPB_AWIDTH-1); |
signal OPB_BE : std_logic_vector(0 to C_OPB_DWIDTH/8-1); |
signal OPB_Clk : std_logic; |
signal OPB_DBus : std_logic_vector(0 to C_OPB_DWIDTH-1); |
signal OPB_RNW : std_logic; |
signal OPB_Rst : std_logic; |
signal OPB_select : std_logic; |
signal OPB_seqAddr : std_logic; |
signal Sln_DBus : std_logic_vector(0 to C_OPB_DWIDTH-1); |
signal Sln_errAck : std_logic; |
signal Sln_retry : std_logic; |
signal Sln_toutSup : std_logic; |
signal Sln_xferAck : std_logic; |
signal opb_s_tx_en : std_logic; |
signal opb_s_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal opb_s_rx_en : std_logic; |
signal opb_s_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal opb_ctl_reg : std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); |
signal tx_thresh : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
signal rx_thresh : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); |
signal opb_fifo_flg : std_logic_vector(C_NUM_FLG-1 downto 0); |
signal opb_dgie : std_logic; |
signal opb_ier : std_logic_vector(C_NUM_INT-1 downto 0); |
signal opb_isr : std_logic_vector(C_NUM_INT-1 downto 0); |
signal opb_isr_clr : std_logic_vector(C_NUM_INT-1 downto 0); |
signal opb_tx_dma_addr : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal opb_tx_dma_ctl : std_logic_vector(0 downto 0); |
signal opb_tx_dma_num : std_logic_vector(15 downto 0); |
signal opb_rx_dma_addr : std_logic_vector(C_OPB_DWIDTH-1 downto 0); |
signal opb_rx_dma_ctl : std_logic_vector(0 downto 0); |
signal opb_rx_dma_num : std_logic_vector(15 downto 0); |
|
constant clk_period : time := 25 ns; |
|
begin -- behavior |
|
-- component instantiation |
DUT: opb_if |
generic map ( |
C_BASEADDR => C_BASEADDR, |
C_HIGHADDR => C_HIGHADDR, |
C_USER_ID_CODE => C_USER_ID_CODE, |
C_OPB_AWIDTH => C_OPB_AWIDTH, |
C_OPB_DWIDTH => C_OPB_DWIDTH, |
C_FAMILY => C_FAMILY, |
C_SR_WIDTH => C_SR_WIDTH, |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, |
C_DMA_EN => C_DMA_EN) |
port map ( |
OPB_ABus => OPB_ABus, |
OPB_BE => OPB_BE, |
OPB_Clk => OPB_Clk, |
OPB_DBus => OPB_DBus, |
OPB_RNW => OPB_RNW, |
OPB_Rst => OPB_Rst, |
OPB_select => OPB_select, |
OPB_seqAddr => OPB_seqAddr, |
Sln_DBus => Sln_DBus, |
Sln_errAck => Sln_errAck, |
Sln_retry => Sln_retry, |
Sln_toutSup => Sln_toutSup, |
Sln_xferAck => Sln_xferAck, |
opb_s_tx_en => opb_s_tx_en, |
opb_s_tx_data => opb_s_tx_data, |
opb_s_rx_en => opb_s_rx_en, |
opb_s_rx_data => opb_s_rx_data, |
opb_ctl_reg => opb_ctl_reg, |
tx_thresh => tx_thresh, |
rx_thresh => rx_thresh, |
opb_fifo_flg => opb_fifo_flg, |
opb_dgie => opb_dgie, |
opb_ier => opb_ier, |
opb_isr => opb_isr, |
opb_isr_clr => opb_isr_clr, |
opb_tx_dma_addr => opb_tx_dma_addr, |
opb_tx_dma_ctl => opb_tx_dma_ctl, |
opb_tx_dma_num => opb_tx_dma_num, |
opb_rx_dma_addr => opb_rx_dma_addr, |
opb_rx_dma_ctl => opb_rx_dma_ctl, |
opb_rx_dma_num => opb_rx_dma_num); |
|
-- clock generation |
process |
begin |
OPB_Clk <= '0'; |
wait for clk_period; |
OPB_Clk <= '1'; |
wait for clk_period; |
end process; |
|
-- waveform generation |
WaveGen_Proc : process |
begin |
OPB_ABus <= (others => '0'); |
OPB_BE <= (others => '0'); |
OPB_DBus <= (others => '0'); |
OPB_RNW <= '0'; |
OPB_select <= '0'; |
OPB_seqAddr <= '0'; |
-- reset active |
OPB_Rst <= '1'; |
wait for 100 ns; |
-- reset inactive |
OPB_Rst <= '0'; |
|
|
-- write acess |
wait until rising_edge(OPB_Clk); |
OPB_ABus <= X"10000000"; |
OPB_select <= '1'; |
OPB_RNW <= '0'; |
OPB_DBus <= X"12345678"; |
|
for i in 0 to 3 loop |
wait until rising_edge(OPB_Clk); |
if (Sln_xferAck = '1') then |
exit; |
end if; |
end loop; -- i |
OPB_DBus <= X"00000000"; |
OPB_ABus <= X"00000000"; |
OPB_select <= '0'; |
|
|
-- read acess |
wait until rising_edge(OPB_Clk); |
OPB_ABus <= X"10000000"; |
OPB_select <= '1'; |
OPB_RNW <= '1'; |
|
for i in 0 to 3 loop |
wait until rising_edge(OPB_Clk); |
if (Sln_xferAck = '1') then |
exit; |
end if; |
end loop; -- i |
OPB_ABus <= X"00000000"; |
OPB_select <= '0'; |
|
|
|
wait for 100 ns; |
assert false report "Simulation sucessful" severity failure; |
|
|
end process WaveGen_Proc; |
|
|
|
end behavior; |
|
------------------------------------------------------------------------------- |
|
configuration opb_if_tb_behavior_cfg of opb_if_tb is |
for behavior |
end for; |
end opb_if_tb_behavior_cfg; |
|
------------------------------------------------------------------------------- |
/tx_fifo_emu.vhd
0,0 → 1,38
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
entity tx_fifo_emu is |
generic ( |
C_SR_WIDTH : integer := 8; |
C_TX_CMP_VALUE : integer); |
port ( |
rst : in std_logic; |
tx_clk : in std_logic; |
tx_en : in std_logic; |
tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0)); |
|
end tx_fifo_emu; |
|
architecture behavior of tx_fifo_emu is |
|
signal tx_data_int : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
|
begin -- behavior |
|
tx_data <= tx_data_int; |
|
process(rst, tx_clk) |
begin |
if (rst = '1') then |
tx_data_int <= conv_std_logic_vector(C_TX_CMP_VALUE,C_SR_WIDTH); |
elsif rising_edge(tx_clk) then |
if (tx_en = '1') then |
tx_data_int <= tx_data_int + 1; |
end if; |
end if; |
end process; |
|
end behavior; |
/shift_register_tb.vhd
0,0 → 1,411
------------------------------------------------------------------------------- |
-- Title : Testbench for design "shift_register" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : shift_register_tb.vhd |
-- Author : |
-- Company : |
-- Created : 2007-08-24 |
-- Last update: 2007-11-12 |
-- Platform : |
-- Standard : VHDL'87 |
------------------------------------------------------------------------------- |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2007 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 2007-08-24 1.0 d.koethe Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use IEEE.STD_LOGIC_ARITH.all; |
use IEEE.STD_LOGIC_UNSIGNED.all; |
|
library work; |
use work.opb_spi_slave_pack.all; |
|
------------------------------------------------------------------------------- |
|
entity shift_register_tb is |
|
end shift_register_tb; |
|
------------------------------------------------------------------------------- |
|
architecture behavior of shift_register_tb is |
|
component shift_register |
generic ( |
C_SR_WIDTH : integer; |
C_MSB_FIRST : boolean; |
C_CPOL : integer range 0 to 1; |
C_PHA : integer range 0 to 1); |
port ( |
rst : in std_logic; |
opb_ctl_reg : in std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); |
sclk : in std_logic; |
ss_n : in std_logic; |
mosi : in std_logic; |
miso_o : out std_logic; |
miso_i : in std_logic; |
miso_t : out std_logic; |
sr_tx_clk : out std_logic; |
sr_tx_en : out std_logic; |
sr_tx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); |
sr_rx_clk : out std_logic; |
sr_rx_en : out std_logic; |
sr_rx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end component; |
|
|
component tx_fifo_emu |
generic ( |
C_SR_WIDTH : integer; |
C_TX_CMP_VALUE : integer); |
port ( |
rst : in std_logic; |
tx_clk : in std_logic; |
tx_en : in std_logic; |
tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end component; |
|
component rx_fifo_emu |
generic ( |
C_SR_WIDTH : integer; |
C_RX_CMP_VALUE : integer); |
port ( |
rst : in std_logic; |
rx_clk : in std_logic; |
rx_en : in std_logic; |
rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0)); |
end component; |
|
|
constant C_NUM_TESTS : integer := 3; |
|
-- component generics |
constant C_SR_WIDTH : integer := 8; |
type C_MSB_FIRST_t is array (0 to C_NUM_TESTS) of boolean; |
constant C_MSB_FIRST : C_MSB_FIRST_t := (true, false, true, false); |
type C_CPOL_t is array (0 to C_NUM_TESTS) of integer range 0 to 1; |
constant C_CPOL : C_CPOL_t := (0, 0, 1, 1); |
type C_PHA_t is array (0 to C_NUM_TESTS) of integer range 0 to 1; |
constant C_PHA : C_PHA_t := (0, 0, 0, 0); |
|
constant clk_period : time := 40 ns; |
|
type sig_std_logic_t is array (0 to C_NUM_TESTS) of std_logic; |
type sig_std_logic_vector_t is array (0 to C_NUM_TESTS) of std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
type C_SCLK_INIT_t is array (0 to C_NUM_TESTS) of std_logic; |
constant C_SCLK_INIT : C_SCLK_INIT_t := ('0', '0', '1', '1'); |
|
signal TEST_NUM : integer := 0; |
|
-- component ports |
signal rst : sig_std_logic_t; |
signal sclk : sig_std_logic_t; |
signal cs_n : sig_std_logic_t; |
signal mosi : sig_std_logic_t; |
signal miso_o : sig_std_logic_t; |
signal miso_i : sig_std_logic_t; |
signal miso_t : sig_std_logic_t; |
signal tx_clk : sig_std_logic_t; |
signal tx_en : sig_std_logic_t; |
signal tx_data : sig_std_logic_vector_t; |
signal rx_clk : sig_std_logic_t; |
signal rx_en : sig_std_logic_t; |
signal rx_data : sig_std_logic_vector_t; |
|
-- component ports |
signal s_rst : std_logic; |
signal s_sclk : std_logic; |
signal s_cs_n : std_logic; |
signal s_mosi : std_logic; |
signal s_miso_o : std_logic; |
signal s_miso_i : std_logic; |
signal s_miso_t : std_logic; |
signal s_tx_clk : std_logic; |
signal s_tx_en : std_logic; |
signal s_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
signal s_rx_clk : std_logic; |
signal s_rx_en : std_logic; |
signal s_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); |
|
-- testbench |
constant C_TX_CMP_VALUE : integer := 130; |
constant C_RX_CMP_VALUE : integer := 129; |
|
signal rx_master : std_logic_vector(7 downto 0); |
|
signal opb_ctl_reg: std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); |
|
begin -- behavior |
|
opb_ctl_reg <= "0111"; -- enable all |
|
s_rst <= rst(TEST_NUM); |
s_sclk <= sclk(TEST_NUM); |
s_cs_n <= cs_n(TEST_NUM); |
s_mosi <= mosi(TEST_NUM); |
s_miso_o <= miso_o(TEST_NUM); |
s_miso_i <= miso_i(TEST_NUM); |
s_miso_t <= miso_t(TEST_NUM); |
s_tx_clk <= tx_clk(TEST_NUM); |
s_tx_en <= tx_en(TEST_NUM); |
s_tx_data <= tx_data(TEST_NUM); |
s_rx_clk <= rx_clk(TEST_NUM); |
s_rx_en <= rx_en(TEST_NUM); |
s_rx_data <= rx_data(TEST_NUM); |
|
|
-- component instantiation |
|
i : for i in 0 to 3 generate |
DUT : shift_register |
generic map ( |
C_SR_WIDTH => C_SR_WIDTH, |
C_MSB_FIRST => C_MSB_FIRST(i), |
C_CPOL => C_CPOL(i), |
C_PHA => C_PHA(i)) |
port map ( |
rst => rst(i), |
opb_ctl_reg => opb_ctl_reg, |
sclk => sclk(i), |
ss_n => cs_n(i), |
mosi => mosi(i), |
miso_o => miso_o(i), |
miso_i => miso_i(i), |
miso_t => miso_t(i), |
sr_tx_clk => tx_clk(i), |
sr_tx_en => tx_en(i), |
sr_tx_data => tx_data(i), |
sr_rx_clk => rx_clk(i), |
sr_rx_en => rx_en(i), |
sr_rx_data => rx_data(i)); |
|
|
|
tx_fifo_emu_1 : tx_fifo_emu |
generic map ( |
C_SR_WIDTH => C_SR_WIDTH, |
C_TX_CMP_VALUE => C_TX_CMP_VALUE) |
port map ( |
rst => rst(i), |
tx_clk => tx_clk(i), |
tx_en => tx_en(i), |
tx_data => tx_data(i)); |
|
|
rx_fifo_emu_1 : rx_fifo_emu |
generic map ( |
C_SR_WIDTH => C_SR_WIDTH, |
C_RX_CMP_VALUE => C_RX_CMP_VALUE) |
port map ( |
rst => rst(i), |
rx_clk => rx_clk(i), |
rx_en => rx_en(i), |
rx_data => rx_data(i)); |
end generate i; |
|
|
-- waveform generation |
WaveGen_Proc : process |
variable rx_value : std_logic_vector(7 downto 0); |
variable tx_value : std_logic_vector(7 downto 0); |
begin |
for i in 0 to C_NUM_TESTS loop |
sclk(i) <= C_SCLK_INIT(i); |
cs_n(i) <= '1'; |
mosi(i) <= 'Z'; |
miso_i(i) <= 'Z'; |
-- rst_active |
rst(i) <= '1'; |
end loop; -- i |
------------------------------------------------------------------------------- |
-- Actual Tests |
TEST_NUM <= 0; |
rx_value := conv_std_logic_vector(C_RX_CMP_VALUE, 8); |
tx_value := conv_std_logic_vector(C_TX_CMP_VALUE, 8); |
wait for 100 ns; |
rst(TEST_NUM) <= '0'; |
|
-- CPHA=0 CPOL=0 C_MSB_FIRST=TRUE |
cs_n(TEST_NUM) <= '0'; |
for i in 7 downto 0 loop |
mosi(TEST_NUM) <= rx_value(i); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '1'; |
rx_master(i) <= miso_o(TEST_NUM); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '0'; |
end loop; -- i |
mosi(TEST_NUM) <= 'Z'; |
wait for clk_period/2; |
cs_n(TEST_NUM) <= '1'; |
wait for 100 ns; |
assert (rx_master = tx_value) report "Master Receive Failure" severity warning; |
|
|
-- write 2 byte |
cs_n(TEST_NUM) <= '0'; |
for n in 1 to 2 loop |
rx_value := rx_value +1; |
tx_value := tx_value +1; |
for i in 7 downto 0 loop |
mosi(TEST_NUM) <= rx_value(i); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '1'; |
rx_master(i) <= miso_o(TEST_NUM); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '0'; |
end loop; -- i |
assert (rx_master = tx_value) report "Master Receive Failure" severity warning; |
end loop; -- n |
mosi(TEST_NUM) <= 'Z'; |
wait for clk_period/2; |
cs_n(TEST_NUM) <= '1'; |
--------------------------------------------------------------------------- |
-- Actual Tests |
TEST_NUM <= 1; |
rx_value := conv_std_logic_vector(C_RX_CMP_VALUE, 8); |
tx_value := conv_std_logic_vector(C_TX_CMP_VALUE, 8); |
wait for 100 ns; |
rst(TEST_NUM) <= '0'; |
|
-- CPHA=0 CPOL=0 C_MSB_FIRST=FALSE |
cs_n(TEST_NUM) <= '0'; |
for i in 0 to 7 loop |
mosi(TEST_NUM) <= rx_value(i); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '1'; |
rx_master(i) <= miso_o(TEST_NUM); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '0'; |
end loop; -- i |
mosi(TEST_NUM) <= 'Z'; |
wait for clk_period/2; |
cs_n(TEST_NUM) <= '1'; |
wait for 100 ns; |
assert (rx_master = tx_value) report "Master Receive Failure" severity warning; |
|
|
-- write 2 byte |
cs_n(TEST_NUM) <= '0'; |
for n in 1 to 2 loop |
rx_value := rx_value +1; |
tx_value := tx_value +1; |
for i in 0 to 7 loop |
mosi(TEST_NUM) <= rx_value(i); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '1'; |
rx_master(i) <= miso_o(TEST_NUM); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '0'; |
end loop; -- i |
assert (rx_master = tx_value) report "Master Receive Failure" severity warning; |
end loop; -- n |
mosi(TEST_NUM) <= 'Z'; |
wait for clk_period/2; |
cs_n(TEST_NUM) <= '1'; |
|
------------------------------------------------------------------------------- |
TEST_NUM <= 2; |
rx_value := conv_std_logic_vector(C_RX_CMP_VALUE, 8); |
tx_value := conv_std_logic_vector(C_TX_CMP_VALUE, 8); |
wait for 100 ns; |
rst(TEST_NUM) <= '0'; |
|
-- CPHA=0 CPOL=1 C_MSB_FIRST=TRUE |
cs_n(TEST_NUM) <= '0'; |
for i in 7 downto 0 loop |
mosi(TEST_NUM) <= rx_value(i); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '0'; |
wait for clk_period/2; |
sclk(TEST_NUM) <= '1'; |
end loop; -- i |
mosi(TEST_NUM) <= 'Z'; |
wait for clk_period/2; |
cs_n(TEST_NUM) <= '1'; |
wait for 100 ns; |
|
-- write 2 byte |
cs_n(TEST_NUM) <= '0'; |
for n in 1 to 2 loop |
rx_value := rx_value +1; |
for i in 7 downto 0 loop |
mosi(TEST_NUM) <= rx_value(i); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '0'; |
wait for clk_period/2; |
sclk(TEST_NUM) <= '1'; |
end loop; -- i |
end loop; -- n |
mosi(TEST_NUM) <= 'Z'; |
wait for clk_period/2; |
cs_n(TEST_NUM) <= '1'; |
|
------------------------------------------------------------------------------- |
TEST_NUM <= 3; |
rx_value := conv_std_logic_vector(C_RX_CMP_VALUE, 8); |
tx_value := conv_std_logic_vector(C_TX_CMP_VALUE, 8); |
wait for 100 ns; |
rst(TEST_NUM) <= '0'; |
|
-- CPHA=0 CPOL=1 C_MSB_FIRST=FALSE |
cs_n(TEST_NUM) <= '0'; |
for i in 0 to 7 loop |
mosi(TEST_NUM) <= rx_value(i); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '0'; |
wait for clk_period/2; |
sclk(TEST_NUM) <= '1'; |
end loop; -- i |
mosi(TEST_NUM) <= 'Z'; |
wait for clk_period/2; |
cs_n(TEST_NUM) <= '1'; |
wait for 100 ns; |
|
-- write 2 byte |
cs_n(TEST_NUM) <= '0'; |
for n in 1 to 2 loop |
rx_value := rx_value +1; |
for i in 0 to 7 loop |
mosi(TEST_NUM) <= rx_value(i); |
wait for clk_period/2; |
sclk(TEST_NUM) <= '0'; |
wait for clk_period/2; |
sclk(TEST_NUM) <= '1'; |
end loop; -- i |
end loop; -- n |
mosi(TEST_NUM) <= 'Z'; |
wait for clk_period/2; |
cs_n(TEST_NUM) <= '1'; |
|
------------------------------------------------------------------------------- |
|
|
wait for 1 us; |
|
assert false report "Simulation sucessful" severity failure; |
|
|
|
end process WaveGen_Proc; |
|
|
|
end behavior; |
|
------------------------------------------------------------------------------- |
|
configuration shift_register_tb_behavior_cfg of shift_register_tb is |
for behavior |
end for; |
end shift_register_tb_behavior_cfg; |
|
------------------------------------------------------------------------------- |
/fifo_tb.vhd
0,0 → 1,308
------------------------------------------------------------------------------- |
-- Title : Testbench for design "fifo_8bitx16" |
-- Project : |
------------------------------------------------------------------------------- |
-- File : fifo_8bitx16_tb.vhd |
-- Author : |
-- Company : |
-- Created : 2007-09-04 |
-- Last update: 2007-11-12 |
-- Platform : |
-- Standard : VHDL'87 |
------------------------------------------------------------------------------- |
-- Description: |
------------------------------------------------------------------------------- |
-- Copyright (c) 2007 |
------------------------------------------------------------------------------- |
-- Revisions : |
-- Date Version Author Description |
-- 2007-09-04 1.0 d.koethe Created |
------------------------------------------------------------------------------- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.std_logic_unsigned.all; |
use IEEE.STD_LOGIC_ARITH.all; |
|
|
library work; |
use work.txt_util.all; |
------------------------------------------------------------------------------- |
|
entity fifo_tb is |
|
end fifo_tb; |
|
------------------------------------------------------------------------------- |
|
architecture behavior of fifo_tb is |
component fifo |
generic ( |
C_FIFO_WIDTH : integer; |
C_FIFO_SIZE_WIDTH : integer; |
C_SYNC_TO : string); |
port ( |
rst : in std_logic; |
wr_clk : in std_logic; |
wr_en : in std_logic; |
din : in std_logic_vector(C_FIFO_WIDTH-1 downto 0); |
rd_clk : in std_logic; |
rd_en : in std_logic; |
dout : out std_logic_vector(C_FIFO_WIDTH-1 downto 0); |
empty : out std_logic; |
full : out std_logic; |
overflow : out std_logic; |
underflow : out std_logic; |
prog_empty_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_full_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
prog_empty : out std_logic; |
prog_full : out std_logic); |
end component; |
|
-- Testbench |
constant C_FIFO_SIZE : integer := 15; |
constant C_FIFO_WIDTH : integer := 8; |
constant C_FIFO_SIZE_WIDTH : integer := 4; |
|
-- sync to RD |
-- constant C_SYNC_TO : string := "RD"; |
-- constant wr_clk_period : time := 100 ns; |
-- constant rd_clk_period : time := 25 ns; |
|
-- sync to WR |
constant C_SYNC_TO : string := "WR"; |
constant wr_clk_period : time := 25 ns; |
constant rd_clk_period : time := 100 ns; |
|
signal rst : std_logic; |
signal wr_clk : std_logic; |
signal wr_en : std_logic; |
signal din : std_logic_vector(C_FIFO_WIDTH-1 downto 0); |
signal rd_clk : std_logic; |
signal rd_en : std_logic; |
signal dout : std_logic_vector(C_FIFO_WIDTH-1 downto 0); |
signal empty : std_logic; |
signal full : std_logic; |
signal overflow : std_logic; |
signal underflow : std_logic; |
signal prog_empty_thresh : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
signal prog_full_thresh : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); |
signal prog_empty : std_logic; |
signal prog_full : std_logic; |
|
|
|
|
|
signal flags : std_logic_vector(5 downto 0); |
signal wr_clk_int : std_logic; |
signal wr_clk_en : boolean := false; |
|
signal rd_clk_int : std_logic; |
signal rd_clk_en : boolean := false; |
|
|
signal wr_off : boolean := false; |
signal rd_off : boolean := false; |
|
begin -- behavior |
|
process |
begin |
rd_clk_int <= '0'; |
wait for rd_clk_period/2; |
rd_clk_int <= '1'; |
wait for rd_clk_period/2; |
end process; |
|
process |
begin |
wr_clk_int <= '0'; |
wait for wr_clk_period/2; |
wr_clk_int <= '1'; |
wait for wr_clk_period/2; |
end process; |
|
-- component instantiation |
|
|
DUT : fifo |
generic map ( |
C_FIFO_WIDTH => C_FIFO_WIDTH, |
C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, |
C_SYNC_TO => C_SYNC_TO) |
port map ( |
rst => rst, |
wr_clk => wr_clk, |
wr_en => wr_en, |
din => din, |
rd_clk => rd_clk, |
rd_en => rd_en, |
dout => dout, |
empty => empty, |
full => full, |
overflow => overflow, |
underflow => underflow, |
prog_empty_thresh => prog_empty_thresh, |
prog_full_thresh => prog_full_thresh, |
prog_empty => prog_empty, |
prog_full => prog_full); |
|
flags <= prog_empty & |
empty & |
underflow & |
prog_full & |
full & |
overflow; |
|
|
wr_off <= false when (C_SYNC_TO = "RD") else true; |
rd_off <= false when (C_SYNC_TO = "WR") else true; |
|
wr_clk <= wr_clk_int when wr_clk_en else '0'; |
rd_clk <= rd_clk_int when rd_clk_en else '0'; |
|
-- waveform generation |
WaveGen_Proc : process |
variable first : std_logic_vector(7 downto 0) := (others => '0'); |
begin |
wr_en <= '0'; |
din <= (others => 'Z'); |
rd_en <= '0'; |
-- prog_empty assert 2 cycle delay |
-- prog_empty deassert 1 cycle delay |
prog_empty_thresh <= X"4"; |
-- prog_full assert 2 cycle delay |
-- prog_full deassert 1 cycle delay |
prog_full_thresh <= X"B"; |
-- rst active |
rst <= '1'; |
wait for 100 ns; |
rst <= '0'; |
|
-- check reset value |
-- 1: empty/prog_empty |
assert (flags = "110000") report "Flag Reset Value wrong " & str(flags) severity warning; |
|
-- write |
|
wait until falling_edge(wr_clk_int); |
wr_clk_en <= true; |
wr_en <= '1'; |
din <= X"A5"; |
wait until falling_edge(wr_clk_int); |
wr_clk_en <= wr_off; |
wr_en <= '0'; |
din <= (others => 'Z'); |
-- check after 1 write |
-- 1: empty |
assert (flags = "100000") report "Flag after one write wrong " & str(flags) severity warning; |
|
wait for 100 ns; |
|
-- read |
wait until falling_edge(rd_clk_int); |
rd_clk_en <= true; |
rd_en <= '1'; |
wait until falling_edge(rd_clk_int); |
rd_en <= '0'; |
rd_clk_en <= rd_off; |
wait for 100 ns; |
|
-- check reset value |
-- 1: empty/prog_empty |
assert (flags = "110000") report "Flag after one read wrong " & str(flags) severity warning; |
|
-- write 16 byte |
wait until falling_edge(wr_clk_int); |
for i in 1 to 255 loop |
wr_clk_en <= true; |
wr_en <= '1'; |
din <= conv_std_logic_vector(i, din'length); |
wait until falling_edge(wr_clk_int); |
wr_en <= '0'; |
din <= (others => 'Z'); |
wr_clk_en <= wr_off; |
-- report threshold for prog_empty |
if (prog_empty = '0' and first(0) = '0') then |
assert (i = conv_integer(prog_empty_thresh)) |
report "prog_emtpy deassert after " & integer'image(i) & " writes." severity warning; |
first(0) := '1'; |
end if; |
-- report threshold for prog_full |
if (prog_full = '1' and first(1) = '0') then |
assert (i = conv_integer(prog_full_thresh)+1) |
report "prog_full assert after " & integer'image(i) & " writes." severity warning; |
first(1) := '1'; |
end if; |
-- report threshold for full |
if (full = '1') then |
assert (i = C_FIFO_SIZE) report "full assert after " & integer'image(i) & " writes." severity warning; |
exit; |
end if; |
end loop; -- i |
|
-- read |
wait until falling_edge(rd_clk_int); |
for i in 1 to 255 loop |
rd_clk_en <= true; |
rd_en <= '1'; |
if (empty = '0' and underflow = '0') then |
assert (conv_integer(dout) = i) report "Read failure at " & integer'image(i) severity warning; |
end if; |
wait until falling_edge(rd_clk_int); |
wait for 1 ps; |
rd_clk_en <= rd_off; |
rd_en <= '0'; |
|
|
|
-- report threshold for prog_full |
if (prog_full = '0' and first(2) = '0') then |
assert (C_FIFO_SIZE-i = conv_integer(prog_full_thresh)-1) |
report "prog_full deassert after " & integer'image(i) & " reads." severity warning; |
first(2) := '1'; |
end if; |
-- report threshold for prog_empty |
|
if (prog_empty = '1' and first(3) = '0') then |
assert (C_FIFO_SIZE-i = conv_integer(prog_empty_thresh)-2) |
report "prog_empty assert after " & integer'image(i) & " reads." severity warning; |
first(3) := '1'; |
end if; |
-- report threshold for empty |
if (empty = '1' and first(4) = '0') then |
assert (i = C_FIFO_SIZE) |
report "empty assert after " & integer'image(i) & " reads." severity warning; |
first(4) := '1'; |
end if; |
-- report threshold for underflow |
if (underflow = '1') then |
assert (i = C_FIFO_SIZE+1) |
report "underflow assert after " & integer'image(i) & " reads." severity warning; |
exit; |
end if; |
|
end loop; -- i |
|
wait for 100 ns; |
|
assert false report "Simulation Sucessful" severity failure; |
|
|
|
|
end process WaveGen_Proc; |
|
|
|
end behavior; |
|
------------------------------------------------------------------------------- |
|
configuration fifo_tb_behavior_cfg of fifo_tb is |
for behavior |
end for; |
end fifo_tb_behavior_cfg; |
|
------------------------------------------------------------------------------- |
/txt_util.vhd
0,0 → 1,586
library ieee; |
use ieee.std_logic_1164.all; |
use std.textio.all; |
|
|
package txt_util is |
|
-- prints a message to the screen |
procedure print(text: string); |
|
-- prints the message when active |
-- useful for debug switches |
procedure print(active: boolean; text: string); |
|
-- converts std_logic into a character |
function chr(sl: std_logic) return character; |
|
-- converts std_logic into a string (1 to 1) |
function str(sl: std_logic) return string; |
|
-- converts std_logic_vector into a string (binary base) |
function str(slv: std_logic_vector) return string; |
|
-- converts boolean into a string |
function str(b: boolean) return string; |
|
-- converts an integer into a single character |
-- (can also be used for hex conversion and other bases) |
function chr(int: integer) return character; |
|
-- converts integer into string using specified base |
function str(int: integer; base: integer) return string; |
|
-- converts integer to string, using base 10 |
function str(int: integer) return string; |
|
-- convert std_logic_vector into a string in hex format |
function hstr(slv: std_logic_vector) return string; |
|
|
-- functions to manipulate strings |
----------------------------------- |
|
-- convert a character to upper case |
function to_upper(c: character) return character; |
|
-- convert a character to lower case |
function to_lower(c: character) return character; |
|
-- convert a string to upper case |
function to_upper(s: string) return string; |
|
-- convert a string to lower case |
function to_lower(s: string) return string; |
|
|
|
-- functions to convert strings into other formats |
-------------------------------------------------- |
|
-- converts a character into std_logic |
function to_std_logic(c: character) return std_logic; |
|
-- converts a string into std_logic_vector |
function to_std_logic_vector(s: string) return std_logic_vector; |
|
|
|
-- file I/O |
----------- |
|
-- read variable length string from input file |
procedure str_read(file in_file: TEXT; |
res_string: out string); |
|
-- print string to a file and start new line |
procedure print(file out_file: TEXT; |
new_string: in string); |
|
-- print character to a file and start new line |
procedure print(file out_file: TEXT; |
char: in character); |
|
end txt_util; |
|
|
|
|
package body txt_util is |
|
|
|
|
-- prints text to the screen |
|
procedure print(text: string) is |
variable msg_line: line; |
begin |
write(msg_line, text); |
writeline(output, msg_line); |
end print; |
|
|
|
|
-- prints text to the screen when active |
|
procedure print(active: boolean; text: string) is |
begin |
if active then |
print(text); |
end if; |
end print; |
|
|
-- converts std_logic into a character |
|
function chr(sl: std_logic) return character is |
variable c: character; |
begin |
case sl is |
when 'U' => c:= 'U'; |
when 'X' => c:= 'X'; |
when '0' => c:= '0'; |
when '1' => c:= '1'; |
when 'Z' => c:= 'Z'; |
when 'W' => c:= 'W'; |
when 'L' => c:= 'L'; |
when 'H' => c:= 'H'; |
when '-' => c:= '-'; |
end case; |
return c; |
end chr; |
|
|
|
-- converts std_logic into a string (1 to 1) |
|
function str(sl: std_logic) return string is |
variable s: string(1 to 1); |
begin |
s(1) := chr(sl); |
return s; |
end str; |
|
|
|
-- converts std_logic_vector into a string (binary base) |
-- (this also takes care of the fact that the range of |
-- a string is natural while a std_logic_vector may |
-- have an integer range) |
|
function str(slv: std_logic_vector) return string is |
variable result : string (1 to slv'length); |
variable r : integer; |
begin |
r := 1; |
for i in slv'range loop |
result(r) := chr(slv(i)); |
r := r + 1; |
end loop; |
return result; |
end str; |
|
|
function str(b: boolean) return string is |
|
begin |
if b then |
return "true"; |
else |
return "false"; |
end if; |
end str; |
|
|
-- converts an integer into a character |
-- for 0 to 9 the obvious mapping is used, higher |
-- values are mapped to the characters A-Z |
-- (this is usefull for systems with base > 10) |
-- (adapted from Steve Vogwell's posting in comp.lang.vhdl) |
|
function chr(int: integer) return character is |
variable c: character; |
begin |
case int is |
when 0 => c := '0'; |
when 1 => c := '1'; |
when 2 => c := '2'; |
when 3 => c := '3'; |
when 4 => c := '4'; |
when 5 => c := '5'; |
when 6 => c := '6'; |
when 7 => c := '7'; |
when 8 => c := '8'; |
when 9 => c := '9'; |
when 10 => c := 'A'; |
when 11 => c := 'B'; |
when 12 => c := 'C'; |
when 13 => c := 'D'; |
when 14 => c := 'E'; |
when 15 => c := 'F'; |
when 16 => c := 'G'; |
when 17 => c := 'H'; |
when 18 => c := 'I'; |
when 19 => c := 'J'; |
when 20 => c := 'K'; |
when 21 => c := 'L'; |
when 22 => c := 'M'; |
when 23 => c := 'N'; |
when 24 => c := 'O'; |
when 25 => c := 'P'; |
when 26 => c := 'Q'; |
when 27 => c := 'R'; |
when 28 => c := 'S'; |
when 29 => c := 'T'; |
when 30 => c := 'U'; |
when 31 => c := 'V'; |
when 32 => c := 'W'; |
when 33 => c := 'X'; |
when 34 => c := 'Y'; |
when 35 => c := 'Z'; |
when others => c := '?'; |
end case; |
return c; |
end chr; |
|
|
|
-- convert integer to string using specified base |
-- (adapted from Steve Vogwell's posting in comp.lang.vhdl) |
|
function str(int: integer; base: integer) return string is |
|
variable temp: string(1 to 10); |
variable num: integer; |
variable abs_int: integer; |
variable len: integer := 1; |
variable power: integer := 1; |
|
begin |
|
-- bug fix for negative numbers |
abs_int := abs(int); |
|
num := abs_int; |
|
while num >= base loop -- Determine how many |
len := len + 1; -- characters required |
num := num / base; -- to represent the |
end loop ; -- number. |
|
for i in len downto 1 loop -- Convert the number to |
temp(i) := chr(abs_int/power mod base); -- a string starting |
power := power * base; -- with the right hand |
end loop ; -- side. |
|
-- return result and add sign if required |
if int < 0 then |
return '-'& temp(1 to len); |
else |
return temp(1 to len); |
end if; |
|
end str; |
|
|
-- convert integer to string, using base 10 |
function str(int: integer) return string is |
|
begin |
|
return str(int, 10) ; |
|
end str; |
|
|
|
-- converts a std_logic_vector into a hex string. |
function hstr(slv: std_logic_vector) return string is |
variable hexlen: integer; |
variable longslv : std_logic_vector(67 downto 0) := (others => '0'); |
variable hex : string(1 to 16); |
variable fourbit : std_logic_vector(3 downto 0); |
begin |
hexlen := (slv'left+1)/4; |
if (slv'left+1) mod 4 /= 0 then |
hexlen := hexlen + 1; |
end if; |
longslv(slv'left downto 0) := slv; |
for i in (hexlen -1) downto 0 loop |
fourbit := longslv(((i*4)+3) downto (i*4)); |
case fourbit is |
when "0000" => hex(hexlen -I) := '0'; |
when "0001" => hex(hexlen -I) := '1'; |
when "0010" => hex(hexlen -I) := '2'; |
when "0011" => hex(hexlen -I) := '3'; |
when "0100" => hex(hexlen -I) := '4'; |
when "0101" => hex(hexlen -I) := '5'; |
when "0110" => hex(hexlen -I) := '6'; |
when "0111" => hex(hexlen -I) := '7'; |
when "1000" => hex(hexlen -I) := '8'; |
when "1001" => hex(hexlen -I) := '9'; |
when "1010" => hex(hexlen -I) := 'A'; |
when "1011" => hex(hexlen -I) := 'B'; |
when "1100" => hex(hexlen -I) := 'C'; |
when "1101" => hex(hexlen -I) := 'D'; |
when "1110" => hex(hexlen -I) := 'E'; |
when "1111" => hex(hexlen -I) := 'F'; |
when "ZZZZ" => hex(hexlen -I) := 'z'; |
when "UUUU" => hex(hexlen -I) := 'u'; |
when "XXXX" => hex(hexlen -I) := 'x'; |
when others => hex(hexlen -I) := '?'; |
end case; |
end loop; |
return hex(1 to hexlen); |
end hstr; |
|
|
|
-- functions to manipulate strings |
----------------------------------- |
|
|
-- convert a character to upper case |
|
function to_upper(c: character) return character is |
|
variable u: character; |
|
begin |
|
case c is |
when 'a' => u := 'A'; |
when 'b' => u := 'B'; |
when 'c' => u := 'C'; |
when 'd' => u := 'D'; |
when 'e' => u := 'E'; |
when 'f' => u := 'F'; |
when 'g' => u := 'G'; |
when 'h' => u := 'H'; |
when 'i' => u := 'I'; |
when 'j' => u := 'J'; |
when 'k' => u := 'K'; |
when 'l' => u := 'L'; |
when 'm' => u := 'M'; |
when 'n' => u := 'N'; |
when 'o' => u := 'O'; |
when 'p' => u := 'P'; |
when 'q' => u := 'Q'; |
when 'r' => u := 'R'; |
when 's' => u := 'S'; |
when 't' => u := 'T'; |
when 'u' => u := 'U'; |
when 'v' => u := 'V'; |
when 'w' => u := 'W'; |
when 'x' => u := 'X'; |
when 'y' => u := 'Y'; |
when 'z' => u := 'Z'; |
when others => u := c; |
end case; |
|
return u; |
|
end to_upper; |
|
|
-- convert a character to lower case |
|
function to_lower(c: character) return character is |
|
variable l: character; |
|
begin |
|
case c is |
when 'A' => l := 'a'; |
when 'B' => l := 'b'; |
when 'C' => l := 'c'; |
when 'D' => l := 'd'; |
when 'E' => l := 'e'; |
when 'F' => l := 'f'; |
when 'G' => l := 'g'; |
when 'H' => l := 'h'; |
when 'I' => l := 'i'; |
when 'J' => l := 'j'; |
when 'K' => l := 'k'; |
when 'L' => l := 'l'; |
when 'M' => l := 'm'; |
when 'N' => l := 'n'; |
when 'O' => l := 'o'; |
when 'P' => l := 'p'; |
when 'Q' => l := 'q'; |
when 'R' => l := 'r'; |
when 'S' => l := 's'; |
when 'T' => l := 't'; |
when 'U' => l := 'u'; |
when 'V' => l := 'v'; |
when 'W' => l := 'w'; |
when 'X' => l := 'x'; |
when 'Y' => l := 'y'; |
when 'Z' => l := 'z'; |
when others => l := c; |
end case; |
|
return l; |
|
end to_lower; |
|
|
|
-- convert a string to upper case |
|
function to_upper(s: string) return string is |
|
variable uppercase: string (s'range); |
|
begin |
|
for i in s'range loop |
uppercase(i):= to_upper(s(i)); |
end loop; |
return uppercase; |
|
end to_upper; |
|
|
|
-- convert a string to lower case |
|
function to_lower(s: string) return string is |
|
variable lowercase: string (s'range); |
|
begin |
|
for i in s'range loop |
lowercase(i):= to_lower(s(i)); |
end loop; |
return lowercase; |
|
end to_lower; |
|
|
|
-- functions to convert strings into other types |
|
|
-- converts a character into a std_logic |
|
function to_std_logic(c: character) return std_logic is |
variable sl: std_logic; |
begin |
case c is |
when 'U' => |
sl := 'U'; |
when 'X' => |
sl := 'X'; |
when '0' => |
sl := '0'; |
when '1' => |
sl := '1'; |
when 'Z' => |
sl := 'Z'; |
when 'W' => |
sl := 'W'; |
when 'L' => |
sl := 'L'; |
when 'H' => |
sl := 'H'; |
when '-' => |
sl := '-'; |
when others => |
sl := 'X'; |
end case; |
return sl; |
end to_std_logic; |
|
|
-- converts a string into std_logic_vector |
|
function to_std_logic_vector(s: string) return std_logic_vector is |
variable slv: std_logic_vector(s'high-s'low downto 0); |
variable k: integer; |
begin |
k := s'high-s'low; |
for i in s'range loop |
slv(k) := to_std_logic(s(i)); |
k := k - 1; |
end loop; |
return slv; |
end to_std_logic_vector; |
|
|
|
|
|
|
---------------- |
-- file I/O -- |
---------------- |
|
|
|
-- read variable length string from input file |
|
procedure str_read(file in_file: TEXT; |
res_string: out string) is |
|
variable l: line; |
variable c: character; |
variable is_string: boolean; |
|
begin |
|
readline(in_file, l); |
-- clear the contents of the result string |
for i in res_string'range loop |
res_string(i) := ' '; |
end loop; |
-- read all characters of the line, up to the length |
-- of the results string |
for i in res_string'range loop |
read(l, c, is_string); |
res_string(i) := c; |
if not is_string then -- found end of line |
exit; |
end if; |
end loop; |
|
end str_read; |
|
|
-- print string to a file |
procedure print(file out_file: TEXT; |
new_string: in string) is |
|
variable l: line; |
|
begin |
|
write(l, new_string); |
writeline(out_file, l); |
|
end print; |
|
|
-- print character to a file and start new line |
procedure print(file out_file: TEXT; |
char: in character) is |
|
variable l: line; |
|
begin |
|
write(l, char); |
writeline(out_file, l); |
|
end print; |
|
|
|
-- appends contents of a string to a file until line feed occurs |
-- (LF is considered to be the end of the string) |
|
procedure str_write(file out_file: TEXT; |
new_string: in string) is |
begin |
|
for i in new_string'range loop |
print(out_file, new_string(i)); |
if new_string(i) = LF then -- end of string |
exit; |
end if; |
end loop; |
|
end str_write; |
|
|
|
|
end txt_util; |
|
|
|
|