/ 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