1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
--
--
-- !!! ======================== [ WARNING ] ======================== !!!
--
-- QUICK-AND-DIRTY TESTBENCH ... SCHEDULED FOR CLEAN UP
--
-- !!! ======================== [ WARNING ] ======================== !!!
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library std;
use std.env.all;
entity nios_model is
generic(
ADDR_WIDTH : positive := 8; -- Number of address bits in an operation
DATA_WIDTH : positive := 8 -- Number of data bits in an operation
);
port(
-- Avalon-MM Interface
clock : out std_logic;
reset : out std_logic;
rd_req : out std_logic;
wr_req : out std_logic;
addr : out std_logic_vector(ADDR_WIDTH-1 downto 0);
wr_data : out std_logic_vector(DATA_WIDTH-1 downto 0);
rd_data : in std_logic_vector(DATA_WIDTH-1 downto 0);
rd_data_val : in std_logic;
mem_hold : in std_logic
);
end entity;
architecture arch of nios_model is
function half_clk_per( freq : natural ) return time is
begin
return ( (0.5 sec) / real(freq) );
end function;
constant SYS_CLK_PER : time := half_clk_per( 80e6 );
constant SPI_CLK_DIV : positive := 2;
type command_t is ( READ, WRITE );
type operation_t is record
cmd : command_t;
addr : std_logic_vector(ADDR_WIDTH-1 downto 0);
data : std_logic_vector(DATA_WIDTH-1 downto 0);
end record;
type operations_t is array(natural range<>) of operation_t;
constant operations : operations_t := (
(cmd => READ, addr => 8x"55", data => (others => '1') ),
(cmd => READ, addr => 8x"7C", data => (others => '1') ),
(cmd => WRITE, addr => 8x"27", data => 8x"42" ),
(cmd => READ, addr => 8x"27", data => 8x"42" ),
(cmd => WRITE, addr => 8x"90", data => 8x"10" ),
(cmd => WRITE, addr => 8x"91", data => 8x"11" ),
(cmd => WRITE, addr => 8x"92", data => 8x"12" ),
(cmd => WRITE, addr => 8x"93", data => 8x"13" ),
(cmd => WRITE, addr => 8x"A0", data => 8x"20" ),
(cmd => WRITE, addr => 8x"A1", data => 8x"21" ),
(cmd => WRITE, addr => 8x"A2", data => 8x"22" ),
(cmd => WRITE, addr => 8x"A3", data => 8x"23" ),
(cmd => READ, addr => 8x"10", data => 8x"10" ),
(cmd => READ, addr => 8x"11", data => 8x"11" ),
(cmd => READ, addr => 8x"12", data => 8x"12" ),
(cmd => READ, addr => 8x"13", data => 8x"13" ),
(cmd => READ, addr => 8x"20", data => 8x"20" ),
(cmd => READ, addr => 8x"21", data => 8x"21" ),
(cmd => READ, addr => 8x"22", data => 8x"22" ),
(cmd => READ, addr => 8x"23", data => 8x"23" )
);
type state_t is ( IDLE, RUN, CHECK_READ, NEXT_CMD );
signal state : state_t := IDLE;
signal sys_clk : std_logic := '1';
signal sys_rst : std_logic := '1';
begin
sys_clk <= not sys_clk after SYS_CLK_PER;
sys_rst <= '1', '0' after SYS_CLK_PER*5;
clock <= sys_clk;
reset <= sys_rst;
stim_proc : process( sys_clk, sys_rst )
variable op : natural range operations'range := operations'low;
variable clock_count : natural := 0;
begin
if( sys_rst = '1' ) then
op := operations'low;
clock_count := 0;
state <= RUN;
rd_req <= '0';
wr_req <= '0';
addr <= (others => '0');
wr_data <= (others => '0');
elsif( rising_edge(sys_clk) ) then
clock_count := clock_count + 1;
rd_req <= '0';
wr_req <= '0';
addr <= (others => '0');
wr_data <= (others => '0');
case( state ) is
when IDLE =>
if( mem_hold = '0' and clock_count >= operations'length*SPI_CLK_DIV*(ADDR_WIDTH+DATA_WIDTH)+10 ) then
stop(0);
end if;
when RUN =>
clock_count := 0;
if( mem_hold = '0' ) then
case (operations(op).cmd) is
when READ =>
rd_req <= '1';
state <= CHECK_READ;
when WRITE =>
wr_req <= '1';
state <= NEXT_CMD;
end case;
addr <= operations(op).addr;
wr_data <= operations(op).data;
end if;
when CHECK_READ =>
if( rd_data_val = '1' ) then
assert (operations(op).data = rd_data) report "Read data does not match expected!" severity failure;
state <= NEXT_CMD;
end if;
when NEXT_CMD =>
if( mem_hold = '0' and clock_count >= 64 ) then
if( op = operations'high ) then
state <= IDLE;
else
op := op + 1;
state <= RUN;
end if;
end if;
end case;
end if;
end process;
end architecture;
|