📄 tormenta2.vhd
字号:
RSTA => '0', RSTB => '0' ); rxqb1: RAMB4_S1_S16 port map ( ADDRA => lposition, -- Where to put the next sample ADDRB => ADDR(9 downto 2), -- Addressable output DIA(0) => XRSER, -- Input from serial from T1 DIB => gndbus, -- Never input from bus WEA => lramno, -- Enable writing when we're in the top WEB => '0', CLKA => not CLK8192, -- Clock input from T1 CLKB => RRD, -- Clock output from bus ENA => not ldbuf, -- Enable when we're the selected buffer ENB => '1', -- Always enable output (it gets MUXed) DOB => rxq1out(15 downto 0), -- Data output to MUX RSTA => '0', RSTB => '0' ); rxqb2: RAMB4_S1_S16 port map ( ADDRA => lposition, -- Where to put the next sample ADDRB => ADDR(9 downto 2), -- Addressable output DIA(0) => XRSER, -- Input from serial from T1 DIB => gndbus, -- Never input from bus WEA => lramno, -- Enable writing when we're in the top WEB => '0', CLKA => not CLK8192, -- Clock input from T1 CLKB => RRD, -- Clock output from bus ENA => ldbuf, -- Enable when we're the selected buffer ENB => '1', -- Always enable output (it gets MUXed) DOB => rxq2out(15 downto 0), -- Data output to MUX RSTA => '0', RSTB => '0' );clkdiv193: process(lclk,ctlreg(4)) -- Divider from 1.544 Mhz (or 2.048 MHZ for E1) to 8 Khz to drive MK1574 via KHZ8000 pinbegin if (lclk'event and lclk = '1') then cnt193 <= cnt193 + 1; if (ctlreg(4) = '0') then -- For T1 operation -- Go high after 96 samples and -- low after 193 samples if (cnt193 = "01100000") then KHZ8000 <= '1'; elsif (cnt193 = "11000000") then -- *YES* C0 hex *IS* the correct value. I even checked it on a freq. counter! KHZ8000 <= '0'; cnt193 <= "00000000"; end if; else -- For E1 operation, it naturally divides by 256 (being an 8 bit counter) KHZ8000 <= cnt193(7); end if; end if;end process clkdiv193;-- Serial transmit data (TSER) output mux (from RAM outputs)txmux: process (txqt1out, txqt2out, txqb1out, txqb2out,dbuf,ramno,rser)begin if (dbuf = '0') then if (ramno = '0') then XTSER <= txqt1out; else XTSER <= txqb1out; end if; else if (ramno = '0') then XTSER <= txqt2out; else XTSER <= txqb2out; end if; end if; if (ctlreg(5)='1') then -- If in remote serial loopback TSER <= RSER; else TSER <= XTSER; end if;end process txmux;-- Stuff to do on rising edge of TSYSCLKprocess(CLK8192,lcounter(12 downto 0),ctlreg(7))begin -- Make sure we're on the rising edge if (CLK8192'event and CLK8192 = '1') then counter <= counter + 1; -- We latch copies of ramno, dbuf, and position on this clock so that they -- will be stable when the RX buffer stuff needs them on the other edge of the clock lramno <= ramno; ldbuf <= dbuf; lposition <= position; if (lcounter(9 downto 0)="0000000000") then -- Generate TSSYNC signal TSSYNC_LOCAL <= '1'; else TSSYNC_LOCAL <= '0'; end if; -- If we are on an 8 sample boundary, and interrupts are enabled, if (((lcounter(12 downto 0)="0000000000000") and (ctlreg(0)='1'))) then statreg(1) <= '1'; elsif (ctlreg(7)='1' or ctlreg(0)='0') then statreg(1) <= '0'; -- If interrupt ack-ed end if; -- If we are on an 16 sample boundary, twiddle LED's if (lcounter="00000000000000") then -- We make this 3 count sequence, because we need 2/3 green and 1/3 red to make -- yellow. Half and half makes sorta orange (yuch!). Bit 1 of the ledcnt will -- be 0 for 2 counts, then 1 for 1 count. Perfict for making yellow! if (ledcnt="10") then ledcnt <= "00"; -- 3 count sequence else ledcnt <= ledcnt + 1; end if; -- Logic for LED 1 if (ledreg(1 downto 0)="11") then -- If yellow, use count seq. LEDS(0) <= ledcnt(1); LEDS(1) <= not ledcnt(1); else -- Otherwise is static LEDS(1 downto 0) <= not ledreg(1 downto 0); end if; -- Logic for LED 2 if (ledreg(3 downto 2)="11") then -- If yellow, use count seq. LEDS(2) <= ledcnt(1); LEDS(3) <= not ledcnt(1); else -- Otherwise is static LEDS(3 downto 2) <= not ledreg(3 downto 2); end if; -- Logic for LED 3 if (ledreg(5 downto 4)="11") then -- If yellow, use count seq. LEDS(4) <= ledcnt(1); LEDS(5) <= not ledcnt(1); else -- Otherwise is static LEDS(5 downto 4) <= not ledreg(5 downto 4); end if; -- Logic for LED 4 if (ledreg(7 downto 6)="11") then -- If yellow, use count seq. LEDS(6) <= ledcnt(1); LEDS(7) <= not ledcnt(1); else -- Otherwise is static LEDS(7 downto 6) <= not ledreg(7 downto 6); end if; end if; end if;end process;-- Stuff to do on Falling edge of TSYSCLKprocess(CLK8192,counter(9 downto 0)) beginif (CLK8192'event and CLK8192='0') then lcounter <= counter; -- save local copy of counter if (counter(9 downto 0)="0000000000") then RSYNC_REVA <= '1'; -- Generate RSYNC pulse else RSYNC_REVA <= '0'; end if;end if;end process;-- Handle Data input requests rxdata: process (ADDR(11 downto 10), rxq1out, rxq2out, RD, dbuf, statreg)begin -- If in 32 bit space, Send data from the block we're not using if (RD = '0' and ADDR(11) = '0') then RRD <= '1'; -- Assert clock to output RAM -- Mux DATA bus to proper RAMs if (dbuf = '1') then D <= rxq1out; else D <= rxq2out; end if; -- If in 8 bit space, return statreg elsif ((RD='0') and (ADDR(11 downto 10)="11")) then if (BE(1 downto 0) = "00") then -- if C00, return status D(2 downto 0) <= statreg; D(31 downto 3) <= "ZZZZZZZZZZZZZZZZZZZZZZZZ00000"; else -- if C01, return board id D(3 downto 0) <= NOT BOARDID; D(31 downto 4) <= "ZZZZZZZZZZZZZZZZZZZZZZZZ0000"; end if; RRD <= '0'; else -- If in outer space, Data bus should be tri-state D <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; RRD <= '0'; end if;end process rxdata;-- rx serial loopback muxrxmux: process(rser,xtser)begin if (ctlreg(6)='1') then XRSER <= XTSER; else XRSER <= RSER; end if;end process rxmux;-- Handle Writing of RAMs when in 32 bit spacetxdecode: process (WR, CLK, BE, dbuf, D, ADDR)begin -- Make sure when we write to memory that we only -- enable the clock on the actual RAM units if the -- top bit of address is '0', and is a full 32 bit access. if ((addr(11) = '0') and (BE="0000") and (WR='0') and (CLK='1')) then RWR <= '1'; else RWR <= '0'; end if;end process txdecode;-- Select the proper output 1.544 Mhz clockclkmux: process(clkreg, RCLK)begin if (clkreg = "001") then lclk <= RCLK(1); elsif (clkreg = "010") then lclk <= RCLK(2); elsif (clkreg = "011") then lclk <= RCLK(3); elsif (clkreg = "100") then lclk <= RCLK(4); elsif (clkreg = "101") then lclk <= XSYNCIN; else lclk <= RCLK(0); end if; RCLKO <= lclk; XSYNCOUT <= lclk;end process clkmux;-- Stuff to do on positive edge of Local bus clockprocess(CLK,ADDR(11 downto 10),RD,WR) beginif (CLK'event and CLK='1') then -- On positive transition of clock if ((WR='0' or RD='0') and ADDR(11 downto 10)="10") then -- If in our address range waitcnt <= waitcnt + 1; -- Bump state counter if in Dallas' address range else waitcnt <= "000"; -- Otherwise, leave reset end if; if (WR='0' and ADDR(11 downto 10)="11") then -- If to write to our configuration space if (ADDR(7 downto 2)="000000") then if (BE(1 downto 0)="11") then TEST2 <= D(0); -- Write to TEST2 pin (0xC03) elsif (BE(1 downto 0)="10") then ledreg <= D(7 downto 0); -- Write to the LED register (0xC02) elsif (BE(1 downto 0)="01") then ctlreg <= D(7 downto 0); -- Write to the ctlreg register (0xC01) else clkreg <= D(2 downto 0); -- Write to the clkreg register (0xC00) end if; end if; if (ADDR(7 downto 2)="000001") then if (BE(1 downto 0)="00") then ctlreg1 <= D(7 downto 0); -- Write to the ctlreg1 register (0xC04) end if; end if; end if; if ((statreg(1)='0') and (ctlreg(7)='1')) then -- if interrupt acked and de-asserted, ack the ack ctlreg(7) <= '0'; end if; if (ctlreg(0)='0') then -- if interrupts disabled, make sure ack is de-acked ctlreg(7) <= '0'; end if;end if;end process;-- Generate Dallas Read and Write Signals and Wait statesprocess(CLK,ADDR(11 downto 8),RD,WR,waitcnt) beginif ((WR='0' or RD='0') and ADDR(11 downto 10)="10") then -- If during valid read or write -- Stuff for CS for Dallas Chips if (ADDR(9 downto 8)="00") then CS(4 downto 1) <= "1110"; -- Activate CS1 end if; if (ADDR(9 downto 8)="01") then CS(4 downto 1) <= "1101"; -- Activate CS2 end if; if (ADDR(9 downto 8)="10") then CS(4 downto 1) <= "1011"; -- Activate CS3 end if; if (ADDR(9 downto 8)="11") then CS(4 downto 1) <= "0111"; -- Activate CS4 end if; if (waitcnt <= "100") then -- An intermediate cycle (before ready) if (WR='0') then -- If a write cycle, output it DWR <= '0'; else DWR <= '1'; end if; if (RD='0') then -- If a read cycle, output it DRD <= '0'; else DRD <= '1'; end if; end if; if ((waitcnt = "011") and (CLK='0')) then -- If were at 4, were ready, and this will be real one READY <= '0'; end if; if (waitcnt > "100") then -- Count is greater then 4, time to reset everything READY <= '1'; DWR <= '1'; DRD <= '1'; end if;else -- Not in read or write in the appropriate range, reset the stuff READY <= '1'; DWR <= '1'; DRD <= '1'; CS(4 downto 1) <= "1111"; -- No CS outputsend if;if (waitcnt="100" and CLK='1' and WR='0') then -- De-activate the DWR signal at the final half cycle DWR <= '1'; DWR <= '1';end if;if ((WR='0' or RD='0') and ADDR(11 downto 10)/="10") then -- If during not valid read or write READY <= '0'; -- Dont hang the bus for themend if;end process;-- MUX for Frame sync lines depending upon part revisionprocess(tssync_local,rsync_reva,ctlreg1(0 downto 0))begin if (ctlreg1(0 downto 0) = "0") then -- Do output for Rev. A part TSSYNC <= TSSYNC_LOCAL; RSYNC <= RSYNC_REVA; else TSSYNC <= TSSYNC_LOCAL; RSYNC <= TSSYNC_LOCAL; end if;end process;end behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -