All pastes #381182 Raw Edit

Something

public text v1 · immutable
#381182 ·published 2007-03-04 18:08 UTC
rendered paste body
library IEEE;
use IEEE.std_logic_1164.all;  -- defines std_logic types
use IEEE.std_logic_ARITH.ALL;
use IEEE.std_logic_UNSIGNED.ALL;
 
entity Main is
  	port 
  (
     -- bus interface signals --
	LRD: in std_logic; 
	LWR: in std_logic; 
	LW_R: in std_logic; 
	ALE: in std_logic; 
	ADS: in std_logic; 
	BLAST: in std_logic; 
	WAITO: in std_logic;
	LOCKO: in std_logic;
	CS0: in std_logic;
	CS1: in std_logic;
	READY: out std_logic; 
	INT: out std_logic;
	
   LAD: inout std_logic_vector (31 downto 0); 			-- data/address bus
 	LA: in std_logic_vector (8 downto 2); 				-- non-muxed address bus
	lBE: in std_logic_vector (3 downto 0); 				-- byte enables

	IOBits: inout std_logic_vector (71 downto 0);			
	SYNCLK: in std_logic;
	LCLK: in std_logic;

	-- led bits
	LEDS: out std_logic_vector(7 downto 0)

	);
end Main;

architecture dataflow of Main is
constant StepGens: integer := 8;
constant QCounters: integer := 8;
constant PWMGens: integer := 8;

constant PortWidth: integer := 24;
constant BusWidth: integer := 32;

	alias BLE: std_logic is LBE(0);	-- 16 bit mode
   alias BHE: std_logic is LBE(3);	-- 16 bit mode
	alias LA1: std_logic is LBE(1);	-- 8/16 bit mode
	alias LA0: std_logic is LBE(0);	-- 8 bit mode
-- misc global signals --
	signal D: std_logic_vector (BusWidth-1 downto 0);							-- internal data bus
	signal A: std_logic_vector (15 downto 2);
	signal Read: std_logic;
	signal Write: std_logic;
	signal Burst: std_logic;
	signal BurstCount: std_logic_vector (7 downto 0);
	signal NextA: std_logic_vector (15 downto 2);
	signal ArmBurstCounter: std_logic;
	signal test32: std_logic_vector (BusWidth-1 downto 0);

-- decodes --

--	IDROM related signals

	signal LoadIDROM: std_logic;
	signal ReadIDROM: std_logic;

	signal LoadIDROMWEn: std_logic;
	signal ReadIDROMWEn: std_logic;

	signal IDROMWEn: std_logic_vector(0 downto 0);
	signal ROMAdd: std_logic_vector(7 downto 0);

-- I/O port related signals

	signal PortSel: std_logic;	
	signal LoadPortCmd: std_logic_vector(3 downto 0);
	signal ReadPortCmd: std_logic_vector(3 downto 0);

	signal DDRSel: std_logic;	
	signal LoadDDRCmd: std_logic_vector(3 downto 0);
	signal ReadDDRCmd: std_logic_vector(3 downto 0);	

-- Step generator related signals
	
	signal StepGenRateSel: std_logic;
	signal LoadStepGenRate: std_logic_vector(StepGens -1 downto 0);
	signal ReadStepGenRate: std_logic_vector(StepGens -1 downto 0);

	signal StepGenAccumSel: std_logic;
	signal LoadStepGenAccum: std_logic_vector(StepGens -1 downto 0);
	signal ReadStepGenAccum: std_logic_vector(StepGens -1 downto 0);
	
	signal StepGenModeSel: std_logic;
	signal LoadStepGenMode: std_logic_vector(StepGens -1 downto 0);
	signal ReadStepGenMode: std_logic_vector(StepGens -1 downto 0);

	signal StepGenDSUTimeSel: std_logic;
	signal LoadStepGenDSUTime: std_logic_vector(StepGens -1 downto 0);
	signal ReadStepGenDSUTime: std_logic_vector(StepGens -1 downto 0);

	signal StepGenDHLDTimeSel: std_logic;
	signal LoadStepGenDHLDTime: std_logic_vector(StepGens -1 downto 0);
	signal ReadStepGenDHLDTime: std_logic_vector(StepGens -1 downto 0);

	signal StepGenPulseWidthSel: std_logic;
	signal LoadStepGenPulseWidth: std_logic_vector(StepGens -1 downto 0);
	signal ReadStepGenPulseWidth: std_logic_vector(StepGens -1 downto 0);

-- Step generators master rate related signals

	signal LoadStepGenBasicRate: std_logic;
	signal ReadStepGenBasicRate: std_logic;
 
	signal StepGenBasicRate: std_logic;

-- Quadrature counter related signals

	signal QCounterSel : std_logic;
	signal LoadQCounter: std_logic_vector(QCounters -1 downto 0);
	signal ReadQCounter: std_logic_vector(QCounters -1 downto 0);
	
	signal QCounterCCRSel : std_logic;
	signal LoadQCounterCCR: std_logic_vector(QCounters -1 downto 0);
	signal ReadQCounterCCR: std_logic_vector(QCounters -1 downto 0);

-- Quadrature counter timestamp reference counter

	signal LoadTSDiv : std_logic;
	signal ReadTSDiv : std_logic;
	signal ReadTS : std_logic;


	signal TimeStampBus: std_logic_vector(15 downto 0);


 function OneOffourdecode(ena1 : std_logic;ena2 : std_logic; dec : std_logic_vector(1 downto 0)) return std_logic_vector is
  variable result   : std_logic_vector(3 downto 0);
  begin
	if ena1 = '1' and ena2 = '1' then
	  	case dec is
			when "00"   => result := "0001";
			when "01"   => result := "0010";
			when "10"   => result := "0100";
      	when "11"   => result := "1000";
        	when others => result := "0000";
      	end case;  
    else
		result := "0000";
	end if;
	return result;
  end OneOfFourDecode;

  function OneOfEightdecode(ena1 : std_logic;ena2 : std_logic; dec : std_logic_vector(2 downto 0)) return std_logic_vector is
  variable result   : std_logic_vector(7 downto 0);
  begin
	if ena1 = '1' and ena2 = '1' then
	  	case dec is
			when "000"   => result := "00000001";
			when "001"   => result := "00000010";
			when "010"   => result := "00000100";
        	when "011"   => result := "00001000";
        	when "100"   => result := "00010000";
        	when "101"   => result := "00100000";
        	when "110"   => result := "01000000";
        	when "111"   => result := "10000000";
        	when others  => result := "00000000";
      	end case;  
    else
		result := "00000000";
	end if;
	return result;
  end OneOfEightDecode;

  function OneOfTwelvedecode(ena1 : std_logic;ena2 : std_logic; dec : std_logic_vector(3 downto 0)) return std_logic_vector is
  variable result   : std_logic_vector(11 downto 0);
  begin
	if ena1 = '1' and ena2 = '1' then
	  	case dec is
			when "0000"   => result := "000000000001";
			when "0001"   => result := "000000000010";
			when "0010"   => result := "000000000100";
        	when "0011"   => result := "000000001000";
        	when "0100"   => result := "000000010000";
        	when "0101"   => result := "000000100000";
        	when "0110"   => result := "000001000000";
        	when "0111"   => result := "000010000000";
			when "1000"   => result := "000100000000";
			when "1001"   => result := "001000000000";
			when "1010"   => result := "010000000000";
        	when "1011"   => result := "100000000000";
         when others  => result :=  "000000000000";
      	end case;  
    else
		result := "000000000000";
	end if;
	return result;
  end OneOftwelveDecode;


-- components --
    component boutreg is
    generic ( size : integer );
    Port ( 
	 		clk : in std_logic;
         ibus : in std_logic_vector(BusWidth-1 downto 0);
         obus : out std_logic_vector(BusWidth-1 downto 0);
         load : in std_logic;
         read : in std_logic;
         dout : out std_logic_vector(size -1 downto 0));
    end component boutreg;
	
	component WordPR is 
		generic(size : integer);
		port (
			clear: in std_logic;
			clk: in std_logic;
			ibus: in std_logic_vector (BusWidth-1 downto 0);
			obus: out std_logic_vector (BusWidth -1 downto 0);
			loadport: in std_logic;
			loadddr: in std_logic;
			readddr: in std_logic;
			portdata: out std_logic_vector (PortWidth -1 downto 0)
		);
	end component WordPR;

	component WordRB is
    	generic(size : integer);
		port (			
	 		obus: out std_logic_vector (BusWidth -1 downto 0);
			readport: in std_logic;
			portdata: in std_logic_vector (PortWidth -1 downto 0) );
	end component WordRB;

	component rategen is
		port ( 
		 	ibus : in std_logic_vector(BusWidth -1downto 0);
			obus : out std_logic_vector(BusWidth -1 downto 0);
			loadbasicrate : in std_logic;
			readbasicrate : in std_logic;
			hold : in std_logic;
			basicrate : out std_logic;
			clk : in std_logic);
	end component rategen;

	component stepgen is
   	port ( 
			clk : in std_logic;
			ibus : in std_logic_vector(BusWidth -1 downto 0);
			obus : out std_logic_vector(BusWidth -1 downto 0);
			loadsteprate : in std_logic;
			loadaccum : in std_logic;
			loadstepmode : in std_logic;
			loaddirsetuptime : in std_logic;
			loaddirholdtime : in std_logic;
			loadpulsewidth : in std_logic;
			readsteprate : in std_logic;
			readaccum : in std_logic;
			readstepmode : in std_logic;
			readdirsetuptime : in std_logic;
			readdirholdtime : in std_logic;
			readpulsewidth : in std_logic;
			basicrate : in std_logic;
			hold : in std_logic;
			outa : out std_logic;
			outb : out std_logic
          );
	end component stepgen;

	component qcounter is
	   port ( 
			obus: out std_logic_vector (31 downto 0);
			ibus: in std_logic_vector (31 downto 0);
			quada: in std_logic;
			quadb: in std_logic;
			index: in std_logic;
			loadccr: in std_logic;
			readccr: in std_logic;
			readcount: in std_logic;
			countclear: in std_logic;
			timestamp: in std_logic_vector (15 downto 0);
			indexmask: in std_logic;
			clk: in std_logic
		);
	end component qcounter;

	component timestamp is
   	port ( 
			ibus : in std_logic_vector(15 downto 0);
         obus : out std_logic_vector(15 downto 0);
			loadtsdiv : in std_logic;
         readts : in std_logic;
			readtsdiv : in std_logic;
			tscount : out std_logic_vector (15 downto 0);
         clk : in std_logic);
	end component timestamp;
    
	 component maskmerge is
    generic ( channels : integer; inputpol: std_logic );
	 port ( ibus : in std_logic_vector(BusWidth -1 downto 0);
           obus : out std_logic_vector(BusWidth -1 downto 0);
           loadmask : in std_logic;
           readmask : in std_logic;
           readstatus : in std_logic;
           sin : in std_logic_vector(channels-1 downto 0);
           clk : in std_logic;
           sout : out std_logic);
   end component maskmerge;

	component spblockram256x32 is 
 		port (
 		clk  : in std_logic; 
		we   : in std_logic;
		re   : in std_logic; 
		add : in std_logic_vector(7 downto 0);  
 		din  : in std_logic_vector(31 downto 0); 
 		dout : out std_logic_vector(31 downto 0)); 

	end component spblockram256x32; 		
	
	
	begin
 
	makeoports: for i in 0 to 2 generate
		oportx: WordPR 
		generic map (size => PortWidth)		
		port map (
		clear => '0',
		clk => LClk,
		ibus => LAD,
		obus => D,
		loadport => LoadPortCmd(i),
		loadddr => LoadDDRCmd(i),
		readddr => ReadDDRCmd(i),
		portdata => IOBits((((i+1)*PortWidth) -1) downto (i*PortWidth)) 
		);	
	end generate;

	makeiports: for i in 0 to 2 generate
		iportx: WordRB 		  
		generic map (size => PortWidth)
		port map (
		obus => D,
		readport => ReadPortCmd(i),
		portdata => IOBits((((i+1)*PortWidth) -1) downto (i*PortWidth)) 
		);	
	end generate;

	StepRategen : RateGen port map(
	 	ibus => LAD,
      obus => D,
      loadbasicrate => LoadStepGenBasicRate,
      readbasicrate => ReadStepGenBasicRate,
		hold => '0',
      basicrate => StepGenBasicRate,
      clk => LClk);

	makestepgens: for i in 0 to StepGens-1 generate
		stepgenx: stepgen port map (
    	clk => LClk,
	 	ibus => LAD,
      obus 	=>	 D,
      loadsteprate => LoadStepGenRate(i),
		loadaccum => LoadStepGenAccum(i),
		loadstepmode => LoadStepGenMode(i),
		loaddirsetuptime => LoadStepGenDSUTime(i),
		loaddirholdtime => LoadStepGenDHLDTime(i),
		loadpulsewidth => LoadStepGenPulseWidth(i),
		readsteprate => ReadStepGenRate(i),
		readaccum => ReadStepGenAccum(i),
		readstepmode => ReadStepGenMode(i),
		readdirsetuptime => ReadStepGenDSUTime(i),
		readdirholdtime => ReadStepGenDHLDTime(i),
		readpulsewidth => ReadStepGenPulseWidth(i),
		basicrate => StepGenBasicRate,
		hold => '0',
      outa => 	IOBits(2*i),  -- densely packed starting with I/O bit 0
      outb =>  IOBits(2*i+1)
          );
	end generate;

	makequadcounters: for i in 0 to QCounters-1 generate
		qcounterx: qcounter port map (
		obus => D,
		ibus => LAD,
		quada => IOBits(24 +3*i),
		quadb => IOBits(25 +3*i),
		index => IOBits(26 +3*i),
		loadccr => LoadQcounterCCR(i),
		readccr => ReadQcounterCCR(i),
		readcount => ReadQcounter(i),
		countclear => LoadQcounter(i),
		timestamp => TimeStampBus,
		indexmask => IOBits(48 + i),
		clk =>	LCLK
		);
	end generate;

	timestampx: timestamp port map( 
		ibus => LAD(15 downto 0),
      obus => D(15 downto 0),
		loadtsdiv => LoadTSDiv ,
      readts => ReadTS,
		readtsdiv =>ReadTSDiv,
		tscount => TimeStampBus,
      clk => LCLK
		);

	IDROM : spblockram256x32 
 		port map (
 		clk  => LCLK, 
		we   => LoadIDROM,
		re   => ReadIDROM,
		add => ROMAdd,
 		din  => LAD, 
 		dout => D
		); 

	IDROMWP : boutreg 
 		generic map (size => 1)

		port map (
			clk  => LCLK,
         ibus => LAD,
         obus => D,
         load => LoadIDROMWEn,
         read => ReadIDROMWEn,
         dout => IDROMWen
		); 
		 		

   LooseEnds: process(A)
	begin
		INT <= '1';
		READY <= '0';
		if LW_R = '1' then  
			ROMAdd <= A(9 downto 2); 		-- on a write we use the delayed address
		else
			ROMAdd <= NextA(9 downto 2); 	-- on a read we use the undelayed address
	   end if;
	end process;


	Decode: process(A) 
	begin	
		-- basic multi decodes are at 256 byte increments (64 longs)
		-- first decode is 256 x 32 ID ROM


		if (A(15 downto 10) = "000000") and Write = '1' and IDROMWEn = "1" then	 --  
			LoadIDROM <= '1';
		else
			LoadIDROM <= '0';
		end if;
		if (A(15 downto 10) = "000000") and Read = '1' then	 --  
			ReadIDROM <= '1';
		else
			ReadIDROM <= '0';
		end if;

		if A(15 downto 8) = x"10" then  -- basic I/O port select
			PortSel <= '1';
		else
			PortSel <= '0';
		end if;

		if A(15 downto 8) = x"11" then	 -- DDR register select
			DDRSel <= '1';
		else
			DDRSel <= '0';
		end if;

		if A(15 downto 8) = x"20" then	 --  stepgen rate register select
			StepGenRateSel <= '1';
		else
			StepGenRateSel <= '0';
		end if;

		if A(15 downto 8) = x"21" then	 --  stepgen Accumumlator low select
			StepGenAccumSel <= '1';
		else
			StepGenAccumSel <= '0';
		end if;

		if A(15 downto 8) = x"22" then	 --  stepgen mode register select
			StepGenModeSel <= '1';
		else
			StepGenModeSel <= '0';
		end if;

		if A(15 downto 8) = x"23" then	 --  stepgen Dir setup time register select
			StepGenDSUTimeSel <= '1';
		else
			StepGenDSUTimeSel <= '0';
		end if;

		if A(15 downto 8) = x"24" then	 --  stepgen Dir hold time register select
			StepGenDHLDTimeSel <= '1';
		else
			StepGenDHLDTimeSel <= '0';
		end if;

		if A(15 downto 8) = x"25" then	 --  stepgen pulse width register select
			StepGenPulseWidthSel <= '1';
		else
			StepGenPulseWidthSel <= '0';
		end if;

		if A(15 downto 8) = x"30" then	 --  QCounter select
			QCounterSel <= '1';
		else
			QCounterSel <= '0';
		end if;

		if A(15 downto 8) = x"31" then	 --  QCounter CCR register select
			QCounterCCRSel <= '1';
		else
			QCounterCCRSel <= '0';
		end if;


		-- basic single decodes are at 16 byte increments (4 longs)
		-- these are mainly for common control logic



		if A(15 downto 4) = x"C00" and Write = '1' then	 --  
			LoadStepGenBasicRate <= '1';
		else
			LoadStepGenBasicRate <= '0';
		end if;
		if A(15 downto 4) = x"C00" and Read = '1' then	 --  
			ReadStepGenBasicRate <= '1';
		else
			ReadStepGenBasicRate <= '0';
		end if;


		if A(15 downto 4) = x"C10" and Write = '1' then	 --  
			LoadTSDiv <= '1';
		else
			LoadTSDiv <= '0';
		end if;
		if A(15 downto 4) = x"C10" and Read = '1' then	 --  
			ReadTSDiv <= '1';
		else
			ReadTSDiv <= '0';
		end if;
		if A(15 downto 4) = x"C20" and Read = '1' then	 --  
			ReadTS <= '1';
		else
			ReadTS <= '0';
		end if;

		if A(15 downto 4) = x"CC0" and Write = '1' then	 --  
			LoadIDROMWEn <= '1';
		else
			LoadIDROMWEn <= '0';
		end if;
		if A(15 downto 4) = x"CC0" and Read = '1' then	 --  
			ReadIDROMWEn<= '1';
		else
			ReadIDROMWEn <= '0';
		end if;


	end process;
	
	PortDecode: process (A,Read,Write)
	begin

		LoadPortCMD <= OneOfFourDecode(PortSel,Write,A(3 downto 2));
		ReadPortCMD <= OneOfFourDecode(PortSel,Read,A(3 downto 2));
		LoadDDRCMD <= OneOfFourDecode(DDRSel,Write,A(3 downto 2));
		ReadDDRCMD <= OneOfFourDecode(DDRSel,Read,A(3 downto 2));

		LoadStepGenRate <= OneOfEightdecode(StepGenRateSel,Write,A(4 downto 2));
		ReadStepGenRate <= OneOfEightdecode(StepGenRateSel,Read,A(4 downto 2));
		LoadStepGenAccum <= OneOfEightdecode(StepGenAccumSel,Write,A(4 downto 2));
		ReadStepGenAccum <= OneOfEightdecode(StepGenAccumSel,Read,A(4 downto 2));
		LoadStepGenMode <= OneOfEightdecode(StepGenModeSel,Write,A(4 downto 2));			 
		ReadStepGenMode <= OneOfEightdecode(StepGenModeSel,Read,A(4 downto 2));	
		LoadStepGenDSUTime <= OneOfEightdecode(StepGenDSUTimeSel,Write,A(4 downto 2));
		ReadStepGenDSUTime <= OneOfEightdecode(StepGenDSUTimeSel,Read,A(4 downto 2));
		LoadStepGenDHLDTime <= OneOfEightdecode(StepGenDHLDTimeSel,Write,A(4 downto 2));
		ReadStepGenDHLDTime <= OneOfEightdecode(StepGenDHLDTimeSel,Read,A(4 downto 2));
		LoadStepGenPulseWidth <= OneOfEightdecode(StepGenPulseWidthSel,Write,A(4 downto 2));
		ReadStepGenPulseWidth <= OneOfEightdecode(StepGenPulseWidthSel,Read,A(4 downto 2));
		
		LoadQCounter <= OneOfEightdecode(QCounterSel,Write,A(4 downto 2));
		ReadQCounter <= OneOfEightdecode(QCounterSel,Read,A(4 downto 2));
		LoadQCounterCCR <= OneOfEightdecode(QCounterCCRSel,Write,A(4 downto 2));
		ReadQCounterCCR <= OneOfEightdecode(QCounterCCRSel,Read,A(4 downto 2));

	end process PortDecode;


	LADDrivers: process (D,Read)
	begin 
		if Read ='1' then	
			LAD <= D;
		else
			LAD <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";			
		end if;
	end process LADDrivers;

	BusCycleGen: process (LCLK)
	begin
		if LCLK'event and LCLK = '1' then
			A <= NextA;							-- always update our latched address
	  		if ADS = '0' then					-- if *ADS then latch address & indicate start of burst
				Burst <= '1';
--				if ArmBurstCounter = '1' then
--					BurstCount <= x"00";		-- BurstCount is just used for testing
--				end if;
			end if;
--			if Burst = '1' then			  -- during burst, increment address
--				if ArmBurstCounter = '1' then
--					BurstCount <= BurstCount + 1;
--				end if;
--			end if;
			if BLAST = '0' then	  			-- end of burst
				Burst <= '0';
--				ArmBurstCounter <= '0';
			end if;
--			if LoadDDRCmd(3) = '1' then
--				ArmBurstCounter <= '1';
--			end if;
		end if; -- lclk
		if ADS = '0' then				 		-- NextA is combinatorial next address
			NextA <=	LAD(15 downto 2);		-- we need this for address lookahead for block RAM
		else
			NextA <= A+1;
		end if;
		
		Write <= Burst and LW_R; 			-- A write is any time during burst when LW_R is high
		Read <= Burst and not LW_R;		-- A read  is any time during burst when LW_R is low			
	end process BusCycleGen;

--	TestLatch: process(lclk,ReadPortCmd)
--	begin
--		if lclk'event and LClk = '1' then
--			if LoadPortCmd(3) = '1' then
--				test32 <= LAD;
--			end if;
--		end if;
--		if ReadPortCmd(3) = '1' then
--			D <= test32;
--		else
--			D <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
--		end if;
--	end process;

	ReadBurst: process(lclk,ReadDDRCmd)
	begin
		if ReadDDRCmd(3) = '1' then
			D(7 downto 0) <= BurstCount;
			D(31 downto 8) <= (others => '0');
		else
			D <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
		end if;
	end process;

end dataflow;