]> jspc29.x-matter.uni-frankfurt.de Git - vhdlbasics.git/commitdiff
moved ecp5-version of sedcheck to vhdlbasics
authorIngo Froehlich <ingo@nomail.fake>
Fri, 22 May 2020 14:50:23 +0000 (16:50 +0200)
committerIngo Froehlich <ingo@nomail.fake>
Fri, 22 May 2020 14:50:23 +0000 (16:50 +0200)
ecp5/sedcheck.vhd [new file with mode: 0644]

diff --git a/ecp5/sedcheck.vhd b/ecp5/sedcheck.vhd
new file mode 100644 (file)
index 0000000..46f6b9d
--- /dev/null
@@ -0,0 +1,225 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.config.all;
+
+library ecp5um;
+use ecp5um.components.all;
+
+entity sedcheck is
+  port(
+    CLK        : in std_logic;
+    ERROR_OUT  : out std_logic;
+    
+    BUS_RX     : in  CTRLBUS_RX;
+    BUS_TX     : out CTRLBUS_TX;
+    DEBUG      : out std_logic_vector(31 downto 0)
+    );
+end entity;
+
+
+architecture sed_arch of sedcheck is
+  component SEDCA
+    generic (
+      OSC_DIV : integer :=4 ;
+      CHECKALWAYS : string :="DISABLED";
+      AUTORECONFIG: string :="OFF" ;
+      MCCLK_FREQ : string :="20" ;
+      DEV_DENSITY : string :="150K" 
+      );
+    port (
+      SEDENABLE : in std_logic;
+      SEDSTART : in std_logic;
+      SEDFRCERR : in std_logic;
+      SEDERR : out std_logic;
+      SEDDONE : out std_logic;
+      SEDINPROG : out std_logic;
+      SEDCLKOUT : out std_logic
+      );
+  end component;  
+  type state_t is (IDLE, INIT_1, INIT_2, INIT_3, START_1, START_2, WAITACTIVE, WAITDONE);
+  signal state          : state_t;
+  signal state_bits     : std_logic_vector(3 downto 0);
+
+  signal sed_edge       : std_logic;
+  signal sed_clock_last : std_logic;
+
+  signal sed_clock      : std_logic;
+  signal sed_done       : std_logic;
+  signal sed_enable     : std_logic;
+  signal sed_error      : std_logic;
+  signal sed_inprogress : std_logic;
+  signal sed_start      : std_logic;
+
+  signal sed_clock_q      : std_logic;
+  signal sed_done_q       : std_logic;
+  signal sed_error_q      : std_logic;
+  signal sed_inprogress_q : std_logic;
+
+  signal control_i      : std_logic_vector(31 downto 0) := (others => '0');
+  signal status_i       : std_logic_vector(31 downto 0);
+  
+  signal run_counter    : unsigned(7 downto 0) := (others => '0');
+  signal error_counter  : unsigned(7 downto 0) := (others => '0');
+  signal timer          : unsigned(5 downto 0);
+  
+begin
+
+sed_clock_last <= sed_clock_q when rising_edge(CLK);
+sed_edge       <= sed_clock_q and not sed_clock_last when rising_edge(CLK);
+
+sed_clock_q      <= sed_clock when rising_edge(CLK);
+sed_done_q       <= sed_done when rising_edge(CLK);
+sed_inprogress_q <= sed_inprogress when rising_edge(CLK);
+sed_error_q      <= sed_error when rising_edge(CLK);
+
+
+---------------------------------------------------------------------------
+-- Status / Control Register for internal data bus
+---------------------------------------------------------------------------
+proc_reg : process begin
+  wait until rising_edge(CLK);
+  BUS_TX.ack     <= '0';
+  BUS_TX.nack    <= '0';
+  BUS_TX.unknown <= '0';
+  
+  if BUS_RX.write = '1' then
+    BUS_TX.ack <= '1';
+    case BUS_RX.addr(1 downto 0) is
+      when "00"   => control_i <= BUS_RX.data;
+      when others => BUS_TX.ack <= '0'; BUS_TX.unknown <= '1';
+    end case;
+  elsif BUS_RX.read = '1' then
+    BUS_TX.ack <= '1';
+    case BUS_RX.addr(1 downto 0) is
+      when "00"   => BUS_TX.data <= control_i;
+      when "01"   => BUS_TX.data <= status_i;
+      when others => BUS_TX.ack <= '0'; BUS_TX.unknown <= '1';
+    end case;
+  end if;
+end process;
+
+---------------------------------------------------------------------------
+-- SED control state machine
+---------------------------------------------------------------------------
+proc_ctrl : process begin
+  wait until rising_edge(CLK);
+  timer <= timer + 1;
+  case state is
+    when IDLE =>
+      sed_enable   <= '0';
+      sed_start    <= '0';
+      if control_i(0) = '1' then
+        state      <= INIT_1;
+        timer      <= "000001";
+      end if;
+    when INIT_1 =>
+      sed_enable   <= '1';
+      sed_start    <= '0';
+      if timer = 0 then
+        state      <= INIT_2;
+      end if;
+    when INIT_2 =>
+      sed_enable   <= '1';
+      sed_start    <= '0';
+      if timer = 0 then
+        state      <= INIT_3;
+      end if;
+    when INIT_3 =>
+      sed_enable   <= '0';
+      sed_start    <= '0';
+      if timer = 0 then
+        state      <= START_1;
+      end if;
+    when START_1 =>
+      sed_enable   <= '1';
+      sed_start    <= '0';
+      if sed_edge = '1' then
+        state      <= START_2;
+      end if;
+    when START_2 =>      
+      sed_enable   <= '1';
+      sed_start    <= '1';
+      if sed_edge = '1' and sed_inprogress_q = '1' then
+        state      <= WAITACTIVE;
+      end if;
+    when WAITACTIVE =>
+      sed_enable   <= '1';
+      sed_start    <= '0';
+      if sed_edge = '1' and sed_done_q = '0' then
+        state      <= WAITDONE;
+      end if;
+    when WAITDONE =>
+      sed_enable   <= '1';
+      sed_start    <= '0';
+      if sed_edge = '1' and sed_inprogress_q = '0' and sed_done_q = '1' then
+        state       <= INIT_1;
+        run_counter <= run_counter + 1;
+        if sed_error_q = '1' then
+          error_counter <= error_counter + 1;
+        end if;
+      end if;
+  end case;
+  
+  if control_i(0) = '0' then
+    sed_enable <= '0';
+    state      <= IDLE;
+  end if;
+  
+end process;
+
+---------------------------------------------------------------------------
+-- Status Information
+---------------------------------------------------------------------------
+state_bits <= x"8" when state = IDLE else
+              x"1" when state = INIT_1 else
+              x"2" when state = INIT_2 else
+              x"3" when state = INIT_3 else
+              x"4" when state = START_1 else
+              x"5" when state = START_2 else
+              x"6" when state = WAITACTIVE else
+              x"7" when state = WAITDONE else
+--               x"9" when state = RESULT else
+              x"F";
+
+status_i(3 downto 0) <= state_bits;
+status_i(4)          <= sed_clock_q;
+status_i(5)          <= sed_enable;
+status_i(6)          <= sed_start;
+status_i(7)          <= sed_done_q;
+status_i(8)          <= sed_inprogress_q;
+status_i(9)          <= sed_error_q;
+status_i(10)         <= sed_edge;
+status_i(15 downto 11) <= (others => '0');
+status_i(23 downto 16) <= std_logic_vector(run_counter);
+status_i(31 downto 24) <= std_logic_vector(error_counter);
+              
+ERROR_OUT <= sed_error;              
+DEBUG     <= status_i when rising_edge(CLK);
+
+---------------------------------------------------------------------------
+-- SED
+---------------------------------------------------------------------------
+THE_SED : SEDGA
+  generic map(
+      CHECKALWAYS  => "DISABLED",
+      SED_CLK_FREQ   => "38.8",
+      DEV_DENSITY  => FPGA_SIZE --"85KUM" 
+      )
+  port map(
+    SEDENABLE => sed_enable,
+    SEDSTART  => sed_start,
+    SEDFRCERR => '0',
+    SEDERR    => sed_error,
+    SEDDONE   => sed_done,
+    SEDINPROG => sed_inprogress,
+    SEDCLKOUT => sed_clock
+    );
+    
+    
+end architecture;