1 |
2 |
federico.a |
library ieee;
|
2 |
|
|
use ieee.std_logic_1164.all;
|
3 |
|
|
use ieee.std_logic_unsigned.all;
|
4 |
|
|
use ieee.std_logic_misc.all;
|
5 |
|
|
use ieee.std_logic_arith.all;
|
6 |
|
|
|
7 |
|
|
use std.textio.all;
|
8 |
|
|
|
9 |
|
|
use work.ahb_package.all;
|
10 |
|
|
|
11 |
|
|
entity slv_mem is
|
12 |
|
|
generic (
|
13 |
|
|
--synopsys translate_off
|
14 |
|
|
dump_file: in string:= "slv_wrap.log";
|
15 |
|
|
dump_type: in integer:= dump_no;
|
16 |
|
|
--synopsys translate_on
|
17 |
|
|
ahb_max_addr: in integer:= 8;
|
18 |
|
|
--***************************************************************
|
19 |
|
|
--parameters for slave access
|
20 |
|
|
--***************************************************************
|
21 |
|
|
s_const_lat_write: in integer:= 1;--1 cycle to save data
|
22 |
|
|
s_const_lat_read: in integer:= 2;--2 cycles to retreave data
|
23 |
|
|
s_write_burst: in integer := no_burst_support;--slave doesn't accept bursts in write!!!
|
24 |
|
|
s_read_burst: in integer:= no_burst_support--slave doesn't accept bursts in read!!!
|
25 |
|
|
);
|
26 |
|
|
port (
|
27 |
|
|
hresetn: in std_logic;
|
28 |
|
|
clk: in std_logic;
|
29 |
|
|
conf: in conf_type_t;
|
30 |
|
|
dma_start: out start_type_t;
|
31 |
|
|
s_wrap_in: in wrap_out_t;
|
32 |
|
|
s_wrap_out: out wrap_in_t);
|
33 |
|
|
end slv_mem;
|
34 |
|
|
|
35 |
|
|
architecture rtl of slv_mem is
|
36 |
|
|
|
37 |
|
|
--synopsys translate_off
|
38 |
|
|
--***************************************************************
|
39 |
|
|
--**** DUMP OF MEMORY *******************************************
|
40 |
|
|
--***************************************************************
|
41 |
|
|
file file_descriptor : TEXT open write_mode is dump_file;
|
42 |
|
|
constant msg1: string(1 to 4):= "MEM ";
|
43 |
|
|
constant msg2: string(1 to 4):= "REG ";
|
44 |
|
|
constant msg3: string(1 to 5):= "DATA ";
|
45 |
|
|
|
46 |
|
|
procedure Write_Message(msg1:string; addr:in integer; msg2:string; value:in integer) is
|
47 |
|
|
variable STR : line;
|
48 |
|
|
begin
|
49 |
|
|
write(STR,now);
|
50 |
|
|
write(STR,STRING'(" "));
|
51 |
|
|
write (STR, msg1);
|
52 |
|
|
write (STR, addr);
|
53 |
|
|
write(STR,STRING'(" "));
|
54 |
|
|
write (STR, msg2);
|
55 |
|
|
write (STR, value);
|
56 |
|
|
writeLine(file_descriptor, STR);
|
57 |
|
|
writeLine(OUTPUT, STR);
|
58 |
|
|
end Write_Message;
|
59 |
|
|
--***************************************************************
|
60 |
|
|
--***************************************************************
|
61 |
|
|
--synopsys translate_on
|
62 |
|
|
|
63 |
|
|
--***************************************************************
|
64 |
|
|
--configuration registers
|
65 |
|
|
--***************************************************************
|
66 |
|
|
signal start_hprot: std_logic_vector(3 downto 0);
|
67 |
|
|
signal start_hsize: std_logic_Vector(2 downto 0);
|
68 |
|
|
signal start_hburst: std_logic_Vector(2 downto 0);
|
69 |
|
|
signal start_hwrite: std_logic;
|
70 |
|
|
signal start_hlocked: std_logic;
|
71 |
|
|
signal start_prior: std_logic;
|
72 |
|
|
signal hsize_reg: std_logic_Vector(2 downto 0);
|
73 |
|
|
signal priority_reg: std_logic;
|
74 |
|
|
signal hburst_reg: std_logic_Vector(2 downto 0);
|
75 |
|
|
signal hprot_reg: std_logic_Vector(3 downto 0);
|
76 |
|
|
signal hlock_reg: std_logic;
|
77 |
|
|
signal trx_dir_reg: std_logic;
|
78 |
|
|
signal extaddr: std_logic_Vector(31 downto 0);
|
79 |
|
|
signal intaddr: std_logic_Vector(15 downto 0);
|
80 |
|
|
signal intmod: std_logic_Vector(15 downto 0);
|
81 |
|
|
signal count_reg: std_logic_Vector(15 downto 0);
|
82 |
|
|
signal dma_go: std_logic;
|
83 |
|
|
--***************************************************************
|
84 |
|
|
--***************************************************************
|
85 |
|
|
|
86 |
|
|
type vect_32 is array (2**ahb_max_addr-1 downto 0) of std_logic_vector (31 downto 0);
|
87 |
|
|
signal mem : vect_32;
|
88 |
|
|
|
89 |
|
|
|
90 |
|
|
|
91 |
|
|
signal s_lat_write_ok, s_lat_read_ok: std_logic;
|
92 |
|
|
signal s_lat_write: integer range 0 to s_const_lat_write;
|
93 |
|
|
signal s_lat_read: integer range 0 to s_const_lat_read;
|
94 |
|
|
--***************************************************************
|
95 |
|
|
--***************************************************************
|
96 |
|
|
|
97 |
|
|
|
98 |
|
|
begin
|
99 |
|
|
|
100 |
|
|
|
101 |
|
|
--***************************************************************
|
102 |
|
|
--***************************************************************
|
103 |
|
|
--** slave part: could be a memory, fifo or register bank *******
|
104 |
|
|
--** here it's only a configuration register bank ***************
|
105 |
|
|
--***************************************************************
|
106 |
|
|
|
107 |
|
|
process(clk, hresetn)
|
108 |
|
|
begin
|
109 |
|
|
if hresetn='0' then
|
110 |
|
|
for i in 0 to 2**ahb_max_addr-1 loop
|
111 |
|
|
mem(i) <= conv_std_logic_vector(i, 32);
|
112 |
|
|
end loop;--i
|
113 |
|
|
elsif clk'event and clk='1' then
|
114 |
|
|
if (s_wrap_in.take='1' and s_lat_write_ok='1') then
|
115 |
|
|
mem(conv_integer(s_wrap_in.addr(ahb_max_addr-1+2 downto 2))) <= s_wrap_in.wdata after 1 ns;
|
116 |
|
|
--synopsys translate_off
|
117 |
|
|
if dump_type/=dump_no then Write_Message(msg1, conv_integer(s_wrap_in.addr(ahb_max_addr-1+2 downto 2)), msg3, conv_integer(s_wrap_in.wdata)); end if;
|
118 |
|
|
--synopsys translate_on
|
119 |
|
|
end if;
|
120 |
|
|
end if;
|
121 |
|
|
end process;
|
122 |
|
|
|
123 |
|
|
s_wrap_out.rdata <= mem(conv_integer(s_wrap_in.addr(ahb_max_addr-1+2 downto 2))) when (s_wrap_in.ask='1' and s_lat_read_ok='1') else (others => '-');
|
124 |
|
|
|
125 |
|
|
|
126 |
|
|
process(clk, hresetn)
|
127 |
|
|
begin
|
128 |
|
|
if hresetn='0' then
|
129 |
|
|
s_lat_write <= s_const_lat_write;
|
130 |
|
|
elsif clk'event and clk='1' then
|
131 |
|
|
if (s_wrap_in.take='1') then
|
132 |
|
|
if (s_lat_write_ok='0') then
|
133 |
|
|
s_lat_write <= s_lat_write-1 after 1 ns;
|
134 |
|
|
elsif (s_write_burst=1) then--accepts bursts .....
|
135 |
|
|
s_lat_write <= 0 after 1 ns;
|
136 |
|
|
else
|
137 |
|
|
s_lat_write <= s_const_lat_write after 1 ns;
|
138 |
|
|
end if;
|
139 |
|
|
else
|
140 |
|
|
s_lat_write <= s_const_lat_write after 1 ns;
|
141 |
|
|
end if;
|
142 |
|
|
end if;
|
143 |
|
|
end process;
|
144 |
|
|
|
145 |
|
|
s_lat_write_ok <= '1' when (s_lat_write=0) else '0';
|
146 |
|
|
s_wrap_out.take_ok <= '1' when (s_wrap_in.take='1' and s_lat_write_ok='1') else '0';
|
147 |
|
|
|
148 |
|
|
process(clk, hresetn)
|
149 |
|
|
begin
|
150 |
|
|
if hresetn='0' then
|
151 |
|
|
s_lat_read <= s_const_lat_read;
|
152 |
|
|
elsif clk'event and clk='1' then
|
153 |
|
|
if (s_wrap_in.ask='1') then
|
154 |
|
|
if (s_lat_read_ok='0') then
|
155 |
|
|
s_lat_read <= s_lat_read-1 after 1 ns;
|
156 |
|
|
elsif (s_read_burst=1) then--accepts bursts .....
|
157 |
|
|
s_lat_read <= 0 after 1 ns;
|
158 |
|
|
else
|
159 |
|
|
s_lat_read <= s_const_lat_read after 1 ns;
|
160 |
|
|
end if;
|
161 |
|
|
else
|
162 |
|
|
s_lat_read <= s_const_lat_read after 1 ns;
|
163 |
|
|
end if;
|
164 |
|
|
end if;
|
165 |
|
|
end process;
|
166 |
|
|
|
167 |
|
|
s_lat_read_ok <= '1' when (s_lat_read=0) else '0';
|
168 |
|
|
s_wrap_out.ask_ok <= '1' when (s_wrap_in.ask='1' and s_lat_read_ok='1') else '0';
|
169 |
|
|
|
170 |
|
|
--**************************************************************************
|
171 |
|
|
-- configuration registers write
|
172 |
|
|
--**************************************************************************
|
173 |
|
|
|
174 |
|
|
conf_reg_pr:process(hresetn, clk)
|
175 |
|
|
variable addr: std_logic_Vector(3 downto 0);
|
176 |
|
|
begin
|
177 |
|
|
if hresetn='0' then
|
178 |
|
|
hsize_reg <= bits32;
|
179 |
|
|
priority_reg <= slave;
|
180 |
|
|
hburst_reg <= incr;
|
181 |
|
|
hprot_reg <= "0011";
|
182 |
|
|
trx_dir_reg <= '0';
|
183 |
|
|
hlock_reg <= locked;
|
184 |
|
|
extaddr <= zeroes;
|
185 |
|
|
intaddr <= zeroes(15 downto 0);
|
186 |
|
|
intmod <= conv_std_logic_vector(4, intmod'length);--mod=+4(+1 word32)
|
187 |
|
|
count_reg <= zeroes(15 downto 0);
|
188 |
|
|
dma_go <= '0';
|
189 |
|
|
elsif clk'event and clk='1' then
|
190 |
|
|
if (conf.write='1') then
|
191 |
|
|
case conf.addr is
|
192 |
|
|
when dma_extadd_addr =>
|
193 |
|
|
extaddr <= conf.wdata;
|
194 |
|
|
when dma_intadd_addr =>
|
195 |
|
|
intaddr <= conf.wdata(15 downto 0);
|
196 |
|
|
when dma_intmod_addr =>
|
197 |
|
|
intmod <= conf.wdata(15 downto 0);
|
198 |
|
|
when dma_type_addr =>
|
199 |
|
|
priority_reg <= conf.wdata(12);
|
200 |
|
|
hsize_reg <= conf.wdata(11 downto 9);
|
201 |
|
|
hburst_reg <= conf.wdata(8 downto 6);
|
202 |
|
|
hprot_reg <= conf.wdata(5 downto 2);
|
203 |
|
|
trx_dir_reg <= conf.wdata(1);
|
204 |
|
|
hlock_reg <= conf.wdata(0);
|
205 |
|
|
when dma_count_addr =>
|
206 |
|
|
count_reg <= conf.wdata(15 downto 0);
|
207 |
|
|
when others => null;
|
208 |
|
|
end case;
|
209 |
|
|
end if;
|
210 |
|
|
if (conf.write='1' and conf.addr=dma_count_addr) then
|
211 |
|
|
dma_go <= '1';
|
212 |
|
|
else
|
213 |
|
|
dma_go <= '0';
|
214 |
|
|
end if;
|
215 |
|
|
end if;
|
216 |
|
|
end process;
|
217 |
|
|
--**************************************************************************
|
218 |
|
|
--**************************************************************************
|
219 |
|
|
|
220 |
|
|
--**************************************************************************
|
221 |
|
|
--**************************************************************************
|
222 |
|
|
dma_start.extaddr <= extaddr;
|
223 |
|
|
dma_start.intaddr <= intaddr;
|
224 |
|
|
dma_start.intmod <= intmod;
|
225 |
|
|
dma_start.hparams <= "000"&priority_reg&hsize_reg&hburst_reg&hprot_reg&trx_dir_reg&hlock_reg;
|
226 |
|
|
dma_start.count <= count_reg;
|
227 |
|
|
dma_start.start <= dma_go;
|
228 |
|
|
|
229 |
|
|
end rtl;
|