/ resolver.vhd
resolver.vhd
  1  library IEEE;
  2  use IEEE.std_logic_1164.all;  -- defines std_logic types
  3  use IEEE.std_logic_ARITH.ALL;
  4  use IEEE.std_logic_UNSIGNED.ALL;
  5  Library UNISIM;
  6  use UNISIM.vcomponents.all;
  7  --
  8  -- Copyright (C) 2007, Peter C. Wallace, Mesa Electronics
  9  -- http://www.mesanet.com
 10  --
 11  -- This program is is licensed under a disjunctive dual license giving you
 12  -- the choice of one of the two following sets of free software/open source
 13  -- licensing terms:
 14  --
 15  --    * GNU General Public License (GPL), version 2.0 or later
 16  --    * 3-clause BSD License
 17  -- 
 18  --
 19  -- The GNU GPL License:
 20  -- 
 21  --     This program is free software; you can redistribute it and/or modify
 22  --     it under the terms of the GNU General Public License as published by
 23  --     the Free Software Foundation; either version 2 of the License, or
 24  --     (at your option) any later version.
 25  -- 
 26  --     This program is distributed in the hope that it will be useful,
 27  --     but WITHOUT ANY WARRANTY; without even the implied warranty of
 28  --     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 29  --     GNU General Public License for more details.
 30  -- 
 31  --     You should have received a copy of the GNU General Public License
 32  --     along with this program; if not, write to the Free Software
 33  --     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 34  -- 
 35  -- 
 36  -- The 3-clause BSD License:
 37  -- 
 38  --     Redistribution and use in source and binary forms, with or without
 39  --     modification, are permitted provided that the following conditions
 40  --     are met:
 41  -- 
 42  --         * Redistributions of source code must retain the above copyright
 43  --           notice, this list of conditions and the following disclaimer.
 44  -- 
 45  --         * Redistributions in binary form must reproduce the above
 46  --           copyright notice, this list of conditions and the following
 47  --           disclaimer in the documentation and/or other materials
 48  --           provided with the distribution.
 49  -- 
 50  --         * Neither the name of Mesa Electronics nor the names of its
 51  --           contributors may be used to endorse or promote products
 52  --           derived from this software without specific prior written
 53  --           permission.
 54  -- 
 55  -- 
 56  -- Disclaimer:
 57  -- 
 58  --     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 59  --     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 60  --     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 61  --     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 62  --     COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 63  --     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 64  --     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 65  --     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 66  --     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 67  --     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 68  --     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 69  --     POSSIBILITY OF SUCH DAMAGE.
 70  -- 
 71  use work.decodedstrobe.all;	
 72  
 73  entity resolver is      
 74    port (
 75  		clk : in std_logic;
 76  		ibus : in std_logic_vector(31 downto 0);
 77        obus : out std_logic_vector(31 downto 0);
 78  		hloadcommand : in std_logic;
 79  		hreadcommand : in std_logic;
 80  		hloaddata : in std_logic;
 81  		hreaddata : in std_logic;
 82  		hreadstatus	 : in std_logic;
 83  		regaddr : in std_logic_vector(2 downto 0);
 84  		readvel : in std_logic; -- for range 0..7
 85  		readpos: in std_logic;-- for range 0..7
 86  		testbit : out std_logic;
 87  		respdmp : out std_logic;   
 88  		respdmm : out std_logic;
 89  		spics : out std_logic;
 90  		spiclk : out std_logic;
 91  		spidi0 : in std_logic;
 92  		spidi1 : in std_logic;
 93  		pwren : out std_logic;
 94  		chan0 : out std_logic;
 95  		chan1 : out std_logic;
 96  		chan2 : out std_logic
 97  		);
 98  		
 99  end resolver;
100  
101  architecture dataflow of resolver is
102  
103  signal iabus: std_logic_vector(11 downto 0);
104  signal idbus: std_logic_vector(23 downto 0); 
105  signal mradd: std_logic_vector(11 downto 0);
106  signal mwadd: std_logic_vector(11 downto 0); 
107  signal mobus: std_logic_vector(31 downto 0);
108  signal mwrite: std_logic;      
109  signal mread: std_logic;	
110  			
111  -- data memory partitioning--			
112  signal muxedmibus: std_logic_vector(31 downto 0); 	-- the data input path to the processor 
113  signal ramdata: std_logic_vector(31 downto 0); 		-- and its sources
114  signal sinedata: std_logic_vector(15 downto 0); 
115  signal iodata: std_logic_vector(31 downto 0); 
116  
117  signal ioradd: std_logic_vector(11 downto 0);
118  
119  signal lloadvel: std_logic;
120  signal writedram: std_logic;
121  
122  -- daq decode signals
123  signal daqreadram: std_logic;
124  signal daqloadmode: std_logic;
125  signal daqreadptr: std_logic;
126  signal daqclear: std_logic;
127  signal startburst: std_logic;
128  signal oldstartburst: std_logic;
129  
130  
131  -- wavegen decode signals
132  signal wgloadrate: std_logic;
133  signal wgloadlength: std_logic;
134  signal wgloadpdmrate: std_logic;
135  signal wgloadtableptr: std_logic;
136  signal wgloadtabledata: std_logic;
137  
138  -- host interface signals
139  signal hcommandreg: std_logic_vector(15 downto 0);
140  signal hdatareg: std_logic_vector(31 downto 0);
141  alias  romwrena : std_logic is hcommandreg(14); -- if high, reset CPU and allow read/write CPU ROM access
142  signal lcommandreg: std_logic_vector(15 downto 0);
143  signal lloadcommand: std_logic;
144  signal lreadcommand: std_logic;
145  signal ldatareg: std_logic_vector(31 downto 0); 
146  signal lloaddata: std_logic;
147  signal lstatusreg: std_logic_vector(31 downto 0); 
148  signal lloadstatus: std_logic;
149  signal lreaddata: std_logic;
150  signal romdata: std_logic_vector(23 downto 0); 
151  signal loadrom: std_logic;
152  signal velramdata: std_logic_vector(31 downto 0); 
153  signal hostreq: std_logic; 
154  signal lloadveli: std_logic; 
155  signal lloadintrate: std_logic;
156  signal lreadpos: std_logic;
157  
158  -- our one bit pwr enable register
159  signal lpwren: std_logic; 
160  signal loadpwren: std_logic;
161  
162  -- our logic for syncing processor to DAQ 
163  signal lreadccount: std_logic; 
164  signal ldeccount: std_logic; 
165  signal lcyclecount: std_logic_vector(7 downto 0); 
166  
167  -- debug test bit out
168  signal ltestbit: std_logic;
169  signal lsettestbit: std_logic;
170  signal lclrtestbit: std_logic;
171  
172  constant UseSmallROM : boolean := false; -- need to promote to generic
173  
174  begin
175  
176   
177  aproc: entity work.Big32v2 -- normally b32qcondmac2.vhd 
178  
179  	port map (
180  		clk      => clk,
181  		reset    => romwrena,
182  		iabus    => iabus,  		-- program address bus
183  		idbus    => idbus,      -- program data bus  
184  		mradd    => mradd,  		-- memory read address
185  		mwadd    => mwadd,  		-- memory write address
186  		mibus    => muxedmibus, -- memory data in bus     
187  		mobus    => mobus, 		-- memory data out bus
188  		mwrite   => mwrite,		-- memory write signal        
189  		mread		=> mread      -- memory read signal 				
190  		);
191  
192  	SmallROM: if UseSmallROM generate
193  		ResolverROM: entity work.resroms 
194  		port map(
195  			addra => hcommandreg(8 downto 0),		-- 512 (x24) till we run out of space
196  			addrb => iabus(8 downto 0),
197  			clk  => clk,
198  			dina  => ibus(23 downto 0),
199  			douta => romdata,
200  			doutb => idbus,
201  			wea	=> loadrom
202  		);
203  	end generate;
204  	
205  	NormalROM: if not UseSmallROM generate
206  		ResolverROM: entity work.resrom 
207  		port map(
208  			addra => hcommandreg(9 downto 0),		-- 1k (x24) till we run out of space
209  			addrb => iabus(9 downto 0),
210  			clk  => clk,
211  			dina  => ibus(23 downto 0),
212  			douta => romdata,
213  			doutb => idbus,
214  			wea	=> loadrom
215  		);
216  	end generate;	 
217  
218  	DataRam : entity work.dpram 
219  	generic map (
220  		width => 32,
221  		depth => 512 --256
222  				)
223  	port map(
224  		addra => mwadd(8 downto 0), --7
225  		addrb => mradd(8 downto 0), --7
226  		clk  => clk,
227  		dina  => mobus,
228  --		douta => 
229  		doutb => ramdata,
230  		wea	=> writedram
231  	 );
232  	 
233  	SineTable : entity work.sine16 
234  	port map (
235  	addr => mradd(9 downto 0),
236  	clk => clk,
237  	din => x"0000",
238  	dout => sinedata,
239  	we => '0'
240  	);
241  
242  	velram: entity work.dpram
243  	generic map (
244  		width => 32,
245  		depth => 8
246  				)
247  	port map(
248  		addra => mwadd(2 downto 0),
249  		addrb => regaddr,
250  		clk  => clk,
251  		dina  => mobus,
252  --		douta => 
253  		doutb => velramdata,
254  		wea	=> lloadvel
255  		); 
256  
257  	interfaceInteg : entity work.OutputInteg	
258  	-- velocity --> position part of integrator (accumulator)
259  	-- is done in hardware so it can run faster than the sample rate (256 times here)
260  	-- so that the (asynchronous) host reads of position do not suffer
261  	-- major aliasing errors
262  	port map(
263  		dspdin => mobus,
264        dspdout => iodata,
265  		hostdout => obus,
266  		dspraddr => mradd(2 downto 0),
267  		dspwaddr => mwadd(2 downto 0),
268  		hostaddr => regaddr,
269  		loadvel => lloadveli,
270  		loadrate => lloadintrate,
271  		dspread => lreadpos,
272  		hostread => readpos,
273  --		testout => testbit,
274  		clk =>  clk
275  		);
276  	
277  	ADAQ: entity work.resolverdaq2
278  	-- A-D samples are written by SPI interface to dual ported RAM and read
279     -- by DSP on other RAM port. Also handles DAQ rate and channel muxing
280  	port map ( 
281  		clk =>  clk,
282  		ibus =>  mobus,
283        obus =>  iodata,
284  		hostaddr =>  mradd(9 downto 0),
285  		ioradd0 => ioradd(0),
286  		readram =>  daqreadram,
287  		loadmode =>  daqloadmode,
288  		clear => daqclear,
289  		readstat => daqreadptr,
290  		startburst=> startburst,
291        spiclk => spiclk,
292        spiin0 => spidi0,
293        spiin1 => spidi1,
294  		spiframe => spics,
295  		channelsel0 => chan0,
296  		channelsel1 => chan1,
297  		channelsel2 => chan2,
298  		testout => testbit
299  		
300         );
301  
302  	AWavegen: entity work.syncwavegen
303  	port map(
304  		clk => clk ,
305  		ibus => mobus, 
306  		loadrate => wgloadrate,
307  		loadlength => wgloadlength,
308  		loadpdmrate => wgloadpdmrate,
309  		loadtableptr => wgloadtableptr,
310  		loadtabledata => wgloadtabledata,
311  		trigger1 => startburst,
312  		pdmouta => respdmp,
313  		pdmoutb => respdmm 
314  	);
315  
316  	iobus:  process(clk,ioradd,ramdata, iodata, sinedata)
317  	begin
318  		if rising_edge(clk) then
319  			ioradd <= mradd;
320  		end if;
321  		
322  		case ioradd(11 downto 10) is
323  			when "00" => muxedmibus <= ramdata;		 		-- bottom 1K is RAM (only 512B now)
324  			when "01" => muxedmibus <= iodata;				-- 1K is I/O space
325  			when "10" =>
326  				muxedmibus(15 downto 0) <= sinedata;		-- next 1K is 16 bit sine table	
327  				muxedmibus(31 downto 16) <= (others => '0');	
328  			when "11" => muxedmibus <= iodata; 				-- top 1K is DAQ read data
329  			when others => null;
330  		end case;
331  		
332  	end process iobus;	
333  
334  	hostinterface : process (clk,lpwren, hloaddata, romwrena, hreadcommand, lcommandreg, hostreq, 
335  	                         hreaddata, ldatareg, romdata, readvel, velramdata, lreadcommand, 
336  									 hcommandreg, lreaddata, hdatareg, lstatusreg, hreadstatus, lreadccount, lcyclecount)
337  	begin
338  		-- first the writes
339  		if rising_edge(clk) then
340  			-- first host writes 
341  			if hloadcommand = '1' then
342  				hcommandreg <= ibus(15 downto 0);
343  				hostreq <= '1';
344  			end if;	
345  			if hloaddata = '1' then 
346  				hdatareg <= ibus;
347  			end if;	
348  
349  			-- next local writes and sync logic 
350  			if lloadcommand = '1' then
351  				lcommandreg <= mobus(15 downto 0);
352  				hostreq <= '0';
353  			end if;	
354  			if lloaddata = '1' then 
355  				ldatareg <= mobus;				
356  			end if;	
357  			
358  			if lloadstatus = '1' then 
359  				lstatusreg <= mobus;				
360  			end if;	
361  			
362  			if loadpwren = '1' then
363  				lpwren <= mobus(0);
364  			end if;	
365  
366  			if oldstartburst = '0' and startburst = '1' then
367  				if ldeccount = '0' then
368  					lcyclecount <= lcyclecount +1;
369  				end if;
370  			else
371  				if ldeccount = '1' then
372  					lcyclecount <= lcyclecount -1;
373  				end if;	
374  			end if;
375  			
376  			if lsettestbit = '1' then
377  				ltestbit <= '1';
378  			end if;	
379  
380  			if lclrtestbit = '1' then
381  				ltestbit <= '0';
382  			end if;	
383  
384  			oldstartburst <= startburst;
385  --			testbit <= startburst;
386  		end if; -- clk
387  		pwren <= not lpwren;											-- resolver drive power enable
388  		
389  		if hloaddata = '1' and romwrena = '1' then		-- write data to rom on host datareg writes
390  			loadrom <= '1';
391  		else
392  			loadrom <= '0';
393  		end if;
394  		
395  		-- then the reads
396  		-- first the host reads
397  		obus <= (others => 'Z');
398  		if hreadcommand = '1' then
399  			obus(15 downto 0) <= lcommandreg;
400  			obus(30 downto 16) <= (others => '0'); 
401  			obus(31) <= hostreq;
402  		end if;	
403  		if hreaddata = '1' then
404  			if romwrena = '0' then							-- normally just read the local data register
405  				obus  <= ldatareg;	
406  			else
407  				obus(23 downto 0) <= romdata;				-- but if romwrena set, read the ROM data
408  				obus(31 downto 24) <=(others => '0');
409  			end if;
410  		end if;	
411  		if hreadstatus = '1' then
412  			obus <= lstatusreg;
413  		end if;	
414  		if readvel = '1' then
415  			obus <= velramdata;
416  		end if;	
417  
418  		-- then the local reads
419  		iodata <= (others => 'Z');
420  		if lreadcommand = '1' then
421  			iodata(15 downto 0) <= hcommandreg;
422  			iodata(30 downto 16) <= (others => '0');
423  			iodata(31) <= hostreq;
424  		end if;
425  		if lreaddata = '1' then
426  			iodata <= hdatareg;
427  		end if;
428  		if lreadccount = '1' then
429  			iodata(7 downto 0) <= lcyclecount;
430  			iodata(31 downto 8) <= (others => '0');
431  		end if;
432  --		testbit <= ltestbit;
433  	end process hostinterface;	
434  
435  	localdecode : process (mradd,mwadd,ioradd,mwrite,mread)
436  	begin
437  
438  		lloadcommand    <= decodedstrobe(mwadd,x"400",mwrite);
439  		lreadcommand    <= decodedstrobe(ioradd,x"400",mread);
440  		lloaddata       <= decodedstrobe(mwadd,x"401",mwrite);
441  		lreaddata       <= decodedstrobe(ioradd,x"401",mread);
442  
443  		daqloadmode     <= decodedstrobe(mwadd,x"402",mwrite);
444  		daqreadptr		 <= decodedstrobe(ioradd,x"402",mread);
445  		daqclear        <= decodedstrobe(mwadd,x"403",mwrite);
446  		daqreadram      <= decodedstrobe(ioradd(11 downto 10),"11",'1');		
447  
448  		wgloadrate      <= decodedstrobe(mwadd,x"404",mwrite);
449  		wgloadlength    <= decodedstrobe(mwadd,x"405",mwrite);
450  		wgloadpdmrate   <= decodedstrobe(mwadd,x"406",mwrite);
451  		wgloadtableptr  <= decodedstrobe(mwadd,x"407",mwrite);
452  		wgloadtabledata <= decodedstrobe(mwadd,x"408",mwrite);
453  		
454  		loadpwren       <= decodedstrobe(mwadd,x"409",mwrite);
455  
456  		ldeccount       <= decodedstrobe(mwadd,x"40A",mwrite);
457  		lreadccount     <= decodedstrobe(ioradd,x"40A",mread);
458  		
459  		lsettestbit		 <= decodedstrobe(mwadd,x"40B",mwrite);
460  		lclrtestbit		 <= decodedstrobe(mwadd,x"40C",mwrite);
461  		lloadintrate	 <= decodedstrobe(mwadd,x"40D",mwrite);
462  		lloadstatus	    <= decodedstrobe(mwadd,x"40E",mwrite);
463  
464  		writedram       <= decodedstrobe(mwadd(11 downto 10),"00",mwrite);
465  		lloadvel        <= decodedstrobe(mwadd(11 downto 3),"010000010",mwrite);-- 0x410 to 0x417
466  
467  		lloadveli       <= decodedstrobe(mwadd(11 downto 3), "010000011",mwrite);-- 0x418 to 0x41F
468  		lreadpos      	 <= decodedstrobe(ioradd(11 downto 3),"010000100",'1');-- 0x420 to 0x427
469  		
470  	end process localdecode;	
471  
472  	
473  end dataflow;
474  
475