Project

General

Profile

Download (11.9 KB) Statistics
| Branch: | Tag: | Revision:
1 c62f5734 Christian Daniel
---------------------------------------------------------------------------------------------------
2
-- Filename    : mt_fil_storage_slow.vhd
3
-- Project     : maintech filter toolbox
4
-- Purpose     : basic data storage for FIR-like filters
5
--               - version for 'slow' filter versions
6
---------------------------------------------------------------------------------------------------
7
8
-----------------------------------------------------------------------------------
9
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
10
-- written by Matthias Kleffel                                                   --
11
--                                                                               --
12
-- This program is free software; you can redistribute it and/or modify          --
13
-- it under the terms of the GNU General Public License as published by          --
14
-- the Free Software Foundation as version 3 of the License, or                  --
15
--                                                                               --
16
-- This program is distributed in the hope that it will be useful,               --
17
-- but WITHOUT ANY WARRANTY; without even the implied warranty of                --
18
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the                  --
19
-- GNU General Public License V3 for more details.                               --
20
--                                                                               --
21
-- You should have received a copy of the GNU General Public License             --
22
-- along with this program. If not, see <http://www.gnu.org/licenses/>.          --
23
-----------------------------------------------------------------------------------
24
25
-------------------------------------------------------------------------------
26
-- mt_fil_dstorage_slow ------------------------------------------------------
27
-------------------------------------------------------------------------------
28
29
library ieee;
30
	use ieee.std_logic_1164.all;
31
	use ieee.numeric_std.all;
32
library work;
33
	use work.all;
34
	use work.mt_toolbox.all;
35
	use work.mt_filter.all;
36
37
entity mt_fil_dstorage_slow is
38
	generic (
39
		CHANNELS : natural;
40
		DEPTH    : natural;
41
		RAMSTYLE : string
42
	);
43
	port (
44
		-- common
45
		clk 	: in  std_logic;
46
		reset 	: in  std_logic;
47
		
48
		-- control
49
		chan    : in  unsigned(log2(CHANNELS)-1 downto 0);
50
		load	: in  std_logic;
51
		start	: in  std_logic;
52
		stop    : in  std_logic;
53
		active	: in  std_logic;
54
		
55
		-- datapath
56
		din		: in  fir_dataword18;
57
		dout1	: out fir_dataword18;
58
		dout2	: out fir_dataword18
59
	);
60
end mt_fil_dstorage_slow;
61
62
architecture rtl of mt_fil_dstorage_slow is
63
64
	--
65
	-- types & rams
66
	--
67
68
	-- derived constants
69
	constant MEMSIZE : natural := CHANNELS * DEPTH;
70
71
	-- internal types
72
	subtype offset_t is unsigned(log2(DEPTH)-1 downto 0);
73
	subtype addr_t is unsigned(log2(MEMSIZE)-1 downto 0);
74
	subtype data_t is fir_dataword18;
75
	type atab_t is array(CHANNELS-1 downto 0) of addr_t;
76
	type pram_t is array(CHANNELS-1 downto 0) of offset_t;
77
	type sram_t is array(MEMSIZE-1 downto 0) of data_t;
78
	
79
	-- create address tables
80
	function get_addr_tab return atab_t is 
81
		variable res : atab_t;
82
	begin
83
		for i in res'range loop
84
			res(i) := to_unsigned(i*DEPTH, addr_t'length);
85
		end loop;
86
		return res;
87
	end get_addr_tab;
88
	constant addr_tab : atab_t := get_addr_tab;
89
	
90
	-- ram ports
91
	signal sram1_we    : std_logic;
92
	signal sram1_waddr : addr_t;
93
	signal sram1_wdata : data_t;
94
	signal sram1_re    : std_logic;
95
	signal sram1_raddr : addr_t;
96
	signal sram1_rdata : data_t := (others=>'0');
97
	signal sram2_we    : std_logic;
98
	signal sram2_waddr : addr_t;
99
	signal sram2_wdata : data_t;
100
	signal sram2_re    : std_logic;
101
	signal sram2_raddr : addr_t;
102
	signal sram2_rdata : data_t := (others=>'0');
103
	
104
	-- actual rams
105
	signal pram  : pram_t := (others=>(others=>'0'));
106
	signal sram1 : sram_t := (others=>(others=>'0'));
107
	signal sram2 : sram_t := (others=>(others=>'0'));
108
	
109
	-- configure rams
110
	attribute syn_ramstyle of pram  : signal is "logic";
111
	attribute syn_ramstyle of sram1 : signal is RAMSTYLE;
112
	attribute syn_ramstyle of sram2 : signal is RAMSTYLE&",no_rw_check";
113
	
114
	
115
	--
116
	-- status
117
	--
118
	
119
	-- delayed control signals
120
	signal start_del   : std_logic_vector(1 downto 0);
121
	signal load_del    : std_logic_vector(2 downto 0);
122
	signal active_del  : std_logic_vector(1 downto 0);
123
	signal stop_del    : std_logic_vector(2 downto 0);
124
	
125
	-- status
126
	signal selchan     : unsigned(log2(CHANNELS)-1 downto 0);
127
	signal baseaddr    : addr_t;
128
	signal woffset     : offset_t;
129
	signal roffset1    : offset_t;
130
	signal roffset2    : offset_t;
131
	
132
begin
133
	
134
	-- validate generics
135
	assert DEPTH>1
136
		report "mt_fil_dstorage_slow: DEPTH must be larger than 1"
137
		severity FAILURE;
138
	
139
	-- control logic
140
	process(clk, reset)
141
		variable offset : offset_t;
142
	begin
143
		if reset='1' then
144
			start_del   <= (others=>'0');
145
			load_del    <= (others=>'0');
146
			active_del  <= (others=>'0');
147
			stop_del    <= (others=>'0');
148
			selchan     <= (others=>'0');
149
			baseaddr    <= (others=>'0');
150
			woffset     <= (others=>'0');
151
			roffset1    <= (others=>'0');
152
			roffset2    <= (others=>'0');
153
			sram1_re    <= '0';
154
			sram1_we    <= '0';
155
			sram1_raddr <= (others=>'0');
156
			sram1_waddr <= (others=>'0');
157
			sram1_wdata <= (others=>'0');
158
			sram2_re    <= '0';
159
			sram2_we    <= '0';
160
			sram2_raddr <= (others=>'0');
161
			sram2_waddr <= (others=>'0');
162
			sram2_wdata <= (others=>'0');
163
		elsif rising_edge(clk) then 
164
			-- set default values
165
			sram1_re <= '0';
166
			sram1_we <= '0';
167
			sram2_re <= '0';
168
			sram2_we <= '0';
169
			
170
			-- create delayed flags
171
			start_del  <= start_del(start_del'left-1 downto 0)   & start;
172
			load_del   <= load_del(load_del'left-1 downto 0)     & load;
173
			active_del <= active_del(active_del'left-1 downto 0) & active;
174
			stop_del   <= stop_del(stop_del'left-1 downto 0)     & stop;
175
176
			-- init status on start of burst
177
			if start='1' then
178
				-- remember channel
179
				selchan  <= chan;
180
				
181
				-- get base-address for selected channels
182
				baseaddr <= addr_tab(to_integer(chan));
183
				
184
				-- init pointers
185
				offset   := pram(to_integer(chan));
186
				woffset  <= offset;
187
				roffset1 <= offset;
188
				if offset=(DEPTH-1)
189
					then roffset2 <= to_unsigned(0,roffset2'length);
190
					else roffset2 <= offset + 1;
191
				end if;
192
			end if;
193
			
194
			-- store sample into ram and increment write-pointer if 'load'-flag is set
195
			if load_del(0)='1' then
196
				-- write sample into ram
197
				sram1_we    <= '1';
198
				sram1_waddr <= baseaddr + woffset;
199
				sram1_wdata <= din;
200
				
201
				-- update write-pointer
202
				woffset <= roffset2; -- 'roffset2' is actually "((woffset+1) mod DEPTH)" here
203
			end if;
204
			if load_del(1)='1' then
205
				-- write-back updated write-pointer
206
				pram(to_integer(selchan)) <= woffset;
207
			end if;
208
			
209
			-- carry sample from sram1 into sram2 if 'stop'-flag is set
210
			if load_del(1)='1' then
211
				sram2_waddr <= baseaddr + woffset;
212
			end if;
213
			if stop_del(2)='1' then
214
				sram2_we    <= '1';
215
				sram2_wdata <= sram1_rdata;
216
			end if;
217
			
218
			-- issue read-requests when active
219
			if active_del(0)='1' then
220
				-- read samples from ram
221
				sram1_re    <= '1';
222
				sram2_re    <= '1';
223
				sram1_raddr <= baseaddr + roffset1;
224
				sram2_raddr <= baseaddr + roffset2;
225
				
226
				-- update read-pointers
227
				if roffset1=0
228
					then roffset1 <= to_unsigned(DEPTH-1,roffset1'length);
229
					else roffset1 <= roffset1 - 1;
230
				end if;
231
				if roffset2=(DEPTH-1)
232
					then roffset2 <= to_unsigned(0,roffset2'length);
233
					else roffset2 <= roffset2 + 1;
234
				end if;
235
			end if;
236
			
237
		end if;
238
	end process;
239
	
240
	-- set output
241
	dout1 <= sram1_rdata when load_del(2)='0' else din;
242
	dout2 <= sram2_rdata;
243
	
244
	-- infer rams
245
	process(clk)
246
	begin
247
		if rising_edge(clk) then 
248
			if sram1_we='1' then
249
				sram1(to_integer(sram1_waddr)) <= sram1_wdata;
250
			end if;
251
			if sram1_re='1' then
252
				sram1_rdata <= sram1(to_integer(sram1_raddr));
253
			end if;
254
			if sram2_we='1' then
255
				sram2(to_integer(sram2_waddr)) <= sram2_wdata;
256
			end if;
257
			if sram2_re='1' then
258
				sram2_rdata <= sram2(to_integer(sram2_raddr));
259
			end if;
260
		end if;
261
	end process;
262
263
end rtl;
264
265
266
267
-------------------------------------------------------------------------------
268
-- mt_fil_storage_slow --------------------------------------------------------
269
-------------------------------------------------------------------------------
270
271
library ieee;
272
	use ieee.std_logic_1164.all;
273
	use ieee.numeric_std.all;
274
library work;
275
	use work.all;
276
	use work.mt_toolbox.all;
277
	use work.mt_filter.all;
278
279
entity mt_fil_storage_slow is
280
	generic (
281
		COEFFS     : fir_coefficients;		-- coefficients
282
		DCHAN      : natural;				-- number of data channels
283
		TAPS       : natural;				-- number of samples in each segment
284
		RAMSTYLE   : string;				-- ram style for inferred memories
285
		ROMSTYLE   : string					-- ram style for coefficent rom
286
	);
287
	port (
288
		-- common
289
		clk 	   : in  std_logic;
290
		reset 	   : in  std_logic;
291
		
292
		-- config
293
		chan       : in  unsigned(log2(DCHAN)-1 downto 0);
294
		
295
		-- input
296
		in_load	   : in  std_logic;
297
		in_start   : in  std_logic;
298
		in_stop    : in  std_logic;
299
		in_active  : in  std_logic;
300
		in_data	   : in  fir_dataword18;
301
		
302
		-- output
303
		out_load   : out std_logic;
304
		out_start  : out std_logic;
305
		out_stop   : out std_logic;
306
		out_active : out std_logic;
307
		out_data1  : out fir_dataword18;
308
		out_data2  : out fir_dataword18;
309
		out_coeff  : out fir_dataword18
310
	);
311
end mt_fil_storage_slow;
312
313
architecture rtl of mt_fil_storage_slow is
314
315
	-- status
316
	signal del_load   : std_logic_vector(1 downto 0);
317
	signal del_start  : std_logic_vector(1 downto 0);
318
	signal del_stop   : std_logic_vector(1 downto 0);
319
	signal del_active : std_logic_vector(1 downto 0);
320
	signal cind       : unsigned(log2(TAPS)-1 downto 0);
321
	
322
	-- coeff rom
323
	constant rom_size : natural := 1 * (2**log2(TAPS));
324
	type rom_t is array (0 to rom_size-1) of fir_dataword18;
325
	function generate_rom return rom_t is
326
		variable rom : rom_t;
327
		variable ssize : natural;
328
	begin
329
		ssize := 2**log2(TAPS);
330
		rom := (others=>(others=>'0'));
331
		for t in 0 to TAPS-1 loop
332
			rom(t) := to_signed(COEFFS(t), 18);
333
		end loop;
334
		return rom;
335
	end generate_rom;
336
	signal rom : rom_t := generate_rom;
337
	
338
	-- don't waste blockram 
339
	attribute syn_romstyle of rom : signal is ROMSTYLE;
340
	attribute syn_ramstyle of rom : signal is ROMSTYLE;
341
	
342
begin
343
	
344
	-- data-buffer
345
	dbuf: entity mt_fil_dstorage_slow
346
		generic map (
347
			CHANNELS => DCHAN,
348
			DEPTH    => TAPS,
349
			RAMSTYLE => RAMSTYLE
350
		)
351
		port map (
352
			clk    => clk,
353
			reset  => reset,
354
			chan   => chan,
355
			load   => in_load,
356
			start  => in_start,
357
			stop   => in_stop,
358
			active => in_active,
359
			din	   => in_data,
360
			dout1  => out_data1,
361
			dout2  => out_data2
362
		);
363
	
364
	-- control logic
365
	process(clk, reset)
366
	begin
367
		if reset='1' then
368
			del_load   <= (others=>'0');
369
			del_start  <= (others=>'0');
370
			del_stop   <= (others=>'0');
371
			del_active <= (others=>'0');
372
			out_load   <= '0';
373
			out_start  <= '0';
374
			out_stop   <= '0';
375
			out_active <= '0';
376
			out_coeff  <= (others=>'0');
377
			cind       <= (others=>'0');
378
		elsif rising_edge(clk) then
379
			-- create delayed control flags
380
			del_load   <= del_load(del_load'left-1 downto 0)     & in_load;
381
			del_start  <= del_start(del_start'left-1 downto 0)   & in_start;
382
			del_stop   <= del_stop(del_stop'left-1 downto 0)     & in_stop;
383
			del_active <= del_active(del_active'left-1 downto 0) & in_active;
384
			
385
			-- output delayed control flags
386
			out_load   <= del_load(1);
387
			out_start  <= del_start(1);
388
			out_stop   <= del_stop(1);
389
			out_active <= del_active(1);
390
			
391
			-- update coeff-indices
392
			if del_start(0)='1' then
393
				cind <= to_unsigned(0, cind'length);
394
			elsif del_active(0)='1' then
395
				cind <= cind + 1;
396
			end if;
397
			
398
			-- output coefficent
399
			out_coeff <= rom(to_integer(cind));
400
		end if;
401
	end process;
402
		
403
end rtl;
Add picture from clipboard (Maximum size: 48.8 MB)