rcu/rcu_pipe.vhd

    1 -----------------------------------------------------------------------------
    2 -- Title      : Pipe-line architecture of RCU.  Allows com with control GUI
    3 -- Project    : ALICE FMD Digitizer Board Controller
    4 ------------------------------------------------------------------------------
    5 -- File       : rcu_pipe.vhd
    6 -- Author     : Christian Holm Christensen  <cholm@nbi.dk>
    7 -- Company    : Niels Bohr Institute
    8 -- Last update: 2006/10/18
    9 -- Platform   : 
   10 ------------------------------------------------------------------------------
   11 -- ALICE FMD Digitiser Board Controller firmware.
   12 --
   13 --              This code takes care of
   14 --              * monitoring voltages, currents, and temperatures.
   15 --              * handle L0 triggers, and sends the appropriate control
   16 --                signals to the VA1 pre-amplifier chips on the FMD hybrid
   17 --                cards.
   18 --              * controls the GTL bus transceivers for the ALTRO's on the
   19 --                card, and of course for it self.
   20 --
   21 --              The code is based on the TPC FEC BC code. The original 
   22 --              authors were
   23 --              * Carmen Gonzalez <Carmen.Gonzalez.Gutierrez@cern.ch> 
   24 --              * Roberto Campagnolo <Roberto.Campagnolo@cern.ch>.
   25 --
   26 --              Some initial development, and a lot of guidance was given by 
   27 --              * Daniel Kirschner <daniel.kirschner@nbi.dk>
   28 --              * Tiago Perez <Tiago.Perez@exp2.physik.uni-giessen.de>
   29 ------------------------------------------------------------------------------
   30 -- Description: 
   31 ------------------------------------------------------------------------------
   32 -- Revisions  :
   33 -- Date        Version  Author  Description
   34 -- 2006/10/02  1.0      cholm	Created
   35 ------------------------------------------------------------------------------
   36 library rcu_model;
   37 use rcu_model.rcu_pack.all;
   38 
   39 ------------------------------------------------------------------------------
   40 architecture pipe_stim of rcu is
   41   constant PERIOD : time      := 25 ns;
   42   constant SIZE   : integer   := 8;
   43   signal   clk_i  : std_logic := '1';
   44   signal   sclk_i : std_logic := '1';
   45   signal   scl_i  : std_logic := '1';
   46   signal   grst_i : std_logic := '0';
   47   signal   l0_i   : std_logic;
   48   signal   l1_i   : std_logic;
   49   signal   l2_i   : std_logic;
   50   signal   l1_ii  : std_logic;
   51   signal   l2_ii  : std_logic;
   52   signal   done_i : boolean   := false;
   53 
   54   ----------------------------------------------------------------------------
   55   type wr_state_t is (idle, got_address, got_data);
   56   type rd_state_t is (idle, got_address, start, output, endit);
   57   type ctrl_t is (idle, start, wait_for_write, wait_for_read);
   58   type exec_st_t is (idle, start, next_instr, rcu_instr, wait_clk,
   59                      altro_instr, altro_instr2, set_bus, strobe,
   60                      wait_strobe, wait_ack, take_data);
   61   type tr_st_t is (idle, gen_l0, wait_to_l1, gen_l1, wait_to_l2, gen_l2);
   62   signal trg_st_i     : tr_st_t;
   63   signal exec_st_i    : exec_st_t;
   64   signal wr_st_i      : wr_state_t;
   65   signal rd_st_i      : rd_state_t;
   66   signal ctrl_st_i    : ctrl_t;
   67   signal enable_rd_i  : std_logic := '0';
   68   signal enable_wr_i  : std_logic := '0';
   69   signal finish_rd_i  : std_logic := '0';
   70   signal finish_wr_i  : std_logic := '0';
   71   signal enable_out_i : std_logic := '0';
   72   signal timeout_i    : std_logic := '0';
   73 
   74   ----------------------------------------------------------------------------
   75   signal ioaddr_i : std_logic_vector(19 downto 0) := (others => '-');
   76   signal idata_i  : std_logic_vector(31 downto 0) := (others => '-');
   77 
   78   ----------------------------------------------------------------------------
   79   constant add_errst    : integer                       := 16#7800#;
   80   constant add_trcfg    : integer                       := 16#7801#;
   81   constant add_trcnt    : integer                       := 16#7802#;
   82   constant add_lwadd    : integer                       := 16#7803#;
   83   constant add_iradd    : integer                       := 16#7804#;
   84   constant add_irdat    : integer                       := 16#7805#;
   85   constant add_pmcfg    : integer                       := 16#7806#;
   86   constant add_chadd    : integer                       := 16#7807#;
   87   constant add_afl      : integer                       := 16#8000#;
   88   signal   errst_i      : std_logic_vector(31 downto 0) := (others => '0');
   89   signal   trcfg_i      : std_logic_vector(31 downto 0) := (others => '0');
   90   signal   trcnt_i      : std_logic_vector(31 downto 0) := (others => '0');
   91   signal   lwadd_i      : std_logic_vector(17 downto 0) := (others => '0');
   92   signal   iradd_i      : std_logic_vector(19 downto 0) := (others => '0');
   93   signal   irdat_i      : std_logic_vector(19 downto 0) := (others => '0');
   94   signal   pmcfg_i      : std_logic_vector(19 downto 0) := (others => '0');
   95   signal   chadd_i      : std_logic_vector(23 downto 0) := (others => '0');
   96   signal   afl_i        : std_logic_vector(31 downto 0) := (others => '0');
   97   signal   load_trcfg_i : std_logic                     := '0';
   98   signal   load_pmcfg_i : std_logic                     := '0';
   99   signal   load_afl_i   : std_logic                     := '0';
  100 
  101   ----------------------------------------------------------------------------
  102   constant add_rs_status   : integer   := 16#6C01#;
  103   constant add_rs_trcfg    : integer   := 16#6C02#;
  104   constant add_rs_trcnt    : integer   := 16#6C03#;
  105   constant add_rs_buf1     : integer   := 16#6C04#;
  106   constant add_rs_buf2     : integer   := 16#6C05#;
  107   constant add_exec        : integer   := 16#0000#;
  108   constant add_abort       : integer   := 16#0800#;
  109   constant add_dcs_on      : integer   := 16#E000#;
  110   constant add_dll_on      : integer   := 16#F000#;
  111   constant add_l1_ttc      : integer   := 16#E800#;
  112   constant add_l1_i2c      : integer   := 16#F800#;
  113   constant add_l1_cmd      : integer   := 16#D800#;
  114   constant add_l1          : integer   := 16#D000#;
  115   constant add_glb_reset   : integer   := 16#2000#;
  116   constant add_fec_reset   : integer   := 16#2001#;
  117   constant add_rcu_reset   : integer   := 16#2002#;
  118   signal   exec_addr_i     : integer   := 0;
  119   signal   cmd_rs_status_i : std_logic := '0';
  120   signal   cmd_rs_trcfg_i  : std_logic := '0';
  121   signal   cmd_rs_trcnt_i  : std_logic := '0';
  122   signal   cmd_rs_buf1_i   : std_logic := '0';
  123   signal   cmd_rs_buf2_i   : std_logic := '0';
  124   signal   cmd_exec_i      : std_logic := '0';
  125   signal   cmd_abort_i     : std_logic := '0';
  126   signal   exec_busy_i     : std_logic := '0';
  127   signal   cmd_dcs_on_i    : std_logic := '0';
  128   signal   cmd_dll_on_i    : std_logic := '0';
  129   signal   cmd_l1_ttc_i    : std_logic := '0';
  130   signal   cmd_l1_i2c_i    : std_logic := '0';
  131   signal   cmd_l1_cmd_i    : std_logic := '0';
  132   signal   cmd_l1_i        : std_logic := '0';
  133   signal   cmd_glb_reset_i : std_logic := '0';
  134   signal   cmd_fec_reset_i : std_logic := '0';
  135   signal   cmd_rcu_reset_i : std_logic := '0';
  136 
  137   ----------------------------------------------------------------------------
  138   signal   icmd_rs_trcfg_i  : std_logic := '0';
  139   signal   icmd_rs_status_i : std_logic := '0';
  140   signal   icmd_rs_trcnt_i  : std_logic := '0';
  141   signal   icmd_trigger_i   : std_logic := '0';
  142 
  143   ----------------------------------------------------------------------------
  144   constant add_imem : integer := 16#7000#;
  145   constant add_pmem : integer := 16#6800#;
  146   constant add_rmem : integer := 16#6000#;
  147   constant add_acl  : integer := 16#6400#;
  148   constant add_dm1l : integer := 16#7400#;
  149   constant add_dm1h : integer := 16#7500#;
  150   constant add_dm2l : integer := 16#7C00#;
  151   constant add_dm2h : integer := 16#7D00#;
  152   constant add_head : integer := 16#4001#;
  153   constant sz_imem  : integer := 256;
  154   constant sz_pmem  : integer := 1024;
  155   constant sz_rmem  : integer := 128;
  156   constant sz_acl   : integer := 256;
  157   constant sz_dmem  : integer := 256;
  158   constant sz_head  : integer := 8;
  159   type imem_t is array (0 to sz_imem-1) of std_logic_vector(23 downto 0);
  160   type pmem_t is array (0 to sz_pmem-1) of std_logic_vector(9 downto 0);
  161   type rmem_t is array (0 to sz_rmem-1) of std_logic_vector(19 downto 0);
  162   type acl_t is array (0 to sz_acl-1) of std_logic_vector(15 downto 0);
  163   type dmem_t is array (0 to sz_dmem-1) of std_logic_vector(19 downto 0);
  164   type head_t is array (0 to sz_head-1) of std_logic_vector(31 downto 0);
  165   signal   imem_i   : imem_t  := (others => (others => '0'));
  166   signal   pmem_i   : pmem_t  := (others => (others => '0'));
  167   signal   rmem_i   : rmem_t  := (others => (others => '0'));
  168   signal   acl_i    : acl_t   := (others => (others => '0'));
  169   signal   dm1l_i   : dmem_t  := (others => (others => '0'));
  170   signal   dm1h_i   : dmem_t  := (others => (others => '0'));
  171   signal   dm2l_i   : dmem_t  := (others => (others => '0'));
  172   signal   dm2h_i   : dmem_t  := (others => (others => '0'));
  173   signal   head_i   : head_t  := (others => (others => '0'));
  174 
  175   ----------------------------------------------------------------------------
  176   -- purpose: Read leading character
  177   procedure read_what (
  178     file input      :     text;
  179     variable what   : out character)
  180   is
  181     variable line_i :     line;
  182     variable good_i :     boolean;
  183   begin  -- function read_what
  184     what   := ' ';
  185     readline(input, line_i);
  186     if not endfile(input) then
  187       read(line_i, what, good_i);
  188     end if;
  189     if not good_i then
  190       what := ' ';
  191     end if;
  192   end procedure read_what;
  193 
  194   ----------------------------------------------------------------------------
  195   -- purpose: Read a real line
  196   procedure read_addr_data (
  197     file input      :     text;            -- File
  198     variable what   : out character;       -- What to do
  199     variable addr   : out string(1 to 7);  -- Address
  200     variable data   : out string(1 to 10))
  201   is
  202     variable line_i :     line;
  203     variable good_i :     boolean;
  204     variable blnk_i :     character       := ' ';
  205     variable what_i :     character       := ' ';
  206     variable addr_i :     string(1 to 7)  := (others => ' ');
  207     variable data_i :     string(1 to 10) := (others => ' ');
  208   begin  -- procedure read_addr_data
  209     what                            := ' ';
  210     addr                            := (others => ' ');
  211     data                            := (others => ' ');
  212     readline(input, line_i);
  213     if not endfile(input) then
  214       read(line_i, what_i, good_i);
  215       what := what_i;
  216       if good_i and what_i /= 'e' then
  217         read(line_i, blnk_i, good_i);
  218         read(line_i, addr_i, good_i);
  219         addr := addr_i;
  220         if good_i then
  221           read(line_i, blnk_i, good_i);
  222           read(line_i, data_i, good_i);
  223           data := data_i;
  224         end if;
  225       end if;
  226     end if;
  227     if not good_i then
  228       what                          := ' ';
  229       addr                          := (others => ' ');
  230       data                          := (others => ' ');
  231     end if;
  232   end procedure read_addr_data;
  233 
  234   ----------------------------------------------------------------------------
  235   -- purpose: Convert std_logic_vector to a string
  236   function slv2str (
  237     constant v   : std_logic_vector)
  238     return string
  239   is
  240     variable ret : string(v'length downto 1);
  241     variable i   : integer;
  242   begin  -- function slv2str
  243     ret := (others => 'X');
  244 
  245     for i in v'range loop
  246       case v(i) is
  247         when 'U'    => ret(i+1) := 'U';
  248         when 'X'    => ret(i+1) := 'X';
  249         when '0'    => ret(i+1) := '0';
  250         when '1'    => ret(i+1) := '1';
  251         when 'Z'    => ret(i+1) := 'Z';
  252         when 'W'    => ret(i+1) := 'W';
  253         when 'L'    => ret(i+1) := 'L';
  254         when 'H'    => ret(i+1) := 'H';
  255         when '-'    => ret(i+1) := '-';
  256         when others => ret(i+1) := 'X';
  257       end case;
  258     end loop;  -- i
  259     return ret;
  260   end function slv2str;
  261 
  262   ----------------------------------------------------------------------------
  263   -- purpose: Convert hex character to std_logic_vector (quad)
  264   function hex2quad (
  265     constant x   : character)
  266     return std_logic_vector
  267   is
  268     variable ret : std_logic_vector(0 to 3);
  269   begin  -- function hex2quad
  270     ret                                     := (others => '0');
  271     case x is
  272       when '0'                       => ret := X"0";
  273       when '1'                       => ret := X"1";
  274       when '2'                       => ret := X"2";
  275       when '3'                       => ret := X"3";
  276       when '4'                       => ret := X"4";
  277       when '5'                       => ret := X"5";
  278       when '6'                       => ret := X"6";
  279       when '7'                       => ret := X"7";
  280       when '8'                       => ret := X"8";
  281       when '9'                       => ret := X"9";
  282       when 'A'|'a'                   => ret := X"A";
  283       when 'B'|'b'                   => ret := X"B";
  284       when 'C'|'c'                   => ret := X"C";
  285       when 'D'|'d'                   => ret := X"D";
  286       when 'E'|'e'                   => ret := X"E";
  287       when 'F'|'f'                   => ret := X"F";
  288       when others                    =>
  289         report "Bad hex character: '" & x & "'" severity warning;
  290     end case;
  291     return ret;
  292   end function hex2quad;
  293 
  294   -- purpose Convert a string (with hex numbers) to a std_logic_vector
  295   function hstr2slv (
  296     constant x   : string)
  297     return std_logic_vector
  298   is
  299     variable j   : integer;
  300     variable ns  : integer    := x'length - 3;
  301     variable ret : std_logic_vector(0 to 4 * ns + 4 - 1);
  302   begin
  303     ret                       := (others => '0');
  304     assert x(1) = '0' and (x(2) = 'x' or x(2) = 'X')
  305       report "Bad hex prefix on: '" & x & "'" severity warning;
  306     for i in 0 to ns loop
  307       j := 4 * i;
  308       ret(j to j + 3) := hex2quad(x(i+3));
  309     end loop;  -- i
  310     return ret;
  311   end function hstr2slv;
  312 
  313   ----------------------------------------------------------------------------
  314   -- purpose: Convert a quad of std_logic to a character
  315   function quad2hex (
  316     constant q   : std_logic_vector(0 to 3))
  317     return character
  318   is
  319     variable ret : character  := '0';
  320     variable x   : integer    := 0;
  321   begin  -- function quad2str
  322     for i in q'range loop
  323       case q(i) is
  324         when 'H' | '1' => x   := x + 2**(3-i);
  325         when 'L' | '0' => null;
  326         when others    =>
  327           report "Unrepresentable bit value " & std_logic'image(q(i)) &
  328             " in " & slv2str(q) severity warning;
  329       end case;
  330     end loop;  -- i
  331     case x is
  332       when 16#0#       => ret := '0';
  333       when 16#1#       => ret := '1';
  334       when 16#2#       => ret := '2';
  335       when 16#3#       => ret := '3';
  336       when 16#4#       => ret := '4';
  337       when 16#5#       => ret := '5';
  338       when 16#6#       => ret := '6';
  339       when 16#7#       => ret := '7';
  340       when 16#8#       => ret := '8';
  341       when 16#9#       => ret := '9';
  342       when 16#A#       => ret := 'A';
  343       when 16#B#       => ret := 'B';
  344       when 16#C#       => ret := 'C';
  345       when 16#D#       => ret := 'D';
  346       when 16#E#       => ret := 'E';
  347       when 16#F#       => ret := 'F';
  348       when others      => null;
  349     end case;
  350     return ret;
  351   end function quad2hex;
  352 
  353   -- purpose: Turn a std_logic_vector into a string
  354   function slv2hstr (
  355     constant v   : std_logic_vector)
  356     return string
  357   is
  358     variable ns  : natural := v'length / 4;
  359     variable ret : string(1 to 2 + ns);
  360     variable j   : integer;
  361     variable q   : std_logic_vector(0 to 3);
  362   begin  -- function slv2hstr
  363     assert v'length mod 4 = 0 report
  364       "Vector length is not a multiplum of 4" severity warning;
  365     ret                    := (others => '0');
  366     ret(2)                 := 'x';
  367     for i in 0 to ns - 1 loop
  368       j                    := 4 * i;
  369       q                    := v(j+3 downto j);
  370       ret(ret'length - i)  := quad2hex(q);
  371     end loop;  -- i
  372     return ret;
  373   end function slv2hstr;
  374 
  375   ----------------------------------------------------------------------------
  376   -- purpose: Turn a std_logic_vector into an integer
  377   function slv2int (
  378     constant x : std_logic_vector)
  379     return integer is
  380   begin  -- function slv2int
  381     return to_integer(unsigned(x));
  382   end function slv2int;
  383 
  384   -- purpose: Turn an integer into a std_logic_vector
  385   function int2slv (
  386     constant x : integer;
  387     constant l : natural)
  388     return std_logic_vector
  389   is
  390     variable ret : std_logic_vector(l - 1 downto 0) := (others => '0');
  391   begin
  392     ret := std_logic_vector(to_unsigned(x, l));
  393     return ret;
  394   end function int2slv;
  395 
  396   ---------------------------------------------------------------------------
  397   -- purpose: calculate parity
  398   function parity (constant x   : std_logic_vector) return std_logic is
  399     variable                tmp : std_logic := '0';
  400   begin  -- function parity
  401     for j in x'range loop
  402       tmp                                   := tmp xor x(j);
  403     end loop;  -- j
  404     return tmp;
  405   end function parity;
  406 begin  -- architecture pipe_stim
  407 
  408   -- purpose: Combinatorics
  409   combi : block is
  410   begin  -- block combi
  411     lvl0 <= l0_i;
  412     lvl1 <= l1_i;
  413     lvl2 <= l2_i;
  414     rclk <= clk_i;
  415     sclk <= sclk_i;
  416     -- grst <= grst_i;
  417   end block combi;
  418 
  419   -- purpose: Provide stimuli
  420   stimuli : process is
  421   begin  -- process stimuli
  422     -- wait for 100 ns;
  423     -- grst_i <= '1';
  424     wait;
  425   end process stimuli;
  426 
  427   -- purpose: Read one line
  428   -- type   : combinational
  429   -- inputs : 
  430   -- outputs: 
  431   control           : process(clk_i, grst_i)
  432     file input_i    : text open read_mode is "/dev/stdin";  -- Input pipe
  433     variable what_i : character;
  434     variable addr_i : string(1 to 7);
  435     variable data_i : string(1 to 10);
  436   begin  -- process read_in
  437 
  438     if grst_i = '0' then
  439       ctrl_st_i <= idle;
  440       done_i    <= false;
  441 
  442     elsif clk_i'event and clk_i = '1' then
  443       enable_wr_i <= '0';
  444       enable_rd_i <= '0';
  445       -- idata_i     <= (others => '0');
  446       -- ioaddr_i    <= (others => '0');
  447       ctrl_st_i   <= ctrl_st_i;
  448 
  449       case ctrl_st_i is
  450         when idle         =>
  451           if not done_i then
  452             read_what(input_i, what_i);
  453             case what_i is
  454               when ' '    =>
  455                 report "At end of file in state " &
  456                   ctrl_t'image(ctrl_st_i) severity error;
  457                 done_i    <= true;
  458               when 's'    =>            -- Start condition
  459                 report "Got start" severity note;
  460                 ctrl_st_i <= start;
  461               when others =>
  462                 report "Unexpected control character '" & what_i &
  463                   "' while in state " & ctrl_t'image(ctrl_st_i)
  464                   severity warning;
  465             end case;
  466           end if;
  467 
  468         when start   =>
  469           read_addr_data(input_i, what_i, addr_i, data_i);
  470           case what_i is
  471             when 'w' =>
  472               -- report "Writing" severity note;
  473               ioaddr_i    <= hstr2slv(addr_i);
  474               idata_i     <= hstr2slv(data_i);
  475               enable_wr_i <= '1';
  476               enable_rd_i <= '0';
  477               ctrl_st_i   <= wait_for_write;
  478 
  479             when 'r' =>
  480               -- report "Reading" severity note;
  481               ioaddr_i    <= hstr2slv(addr_i);
  482               idata_i     <= hstr2slv(data_i);
  483               enable_wr_i <= '0';
  484               enable_rd_i <= '1';
  485               ctrl_st_i   <= wait_for_read;
  486 
  487             when 'e'                 =>
  488               report "Got end" severity note;
  489               enable_wr_i <= '0';
  490               enable_rd_i <= '0';
  491               ctrl_st_i   <= idle;
  492 
  493             when ' ' =>
  494               report "at end of file in state " & ctrl_t'image(ctrl_st_i)
  495                 severity error;
  496               done_i <= true;
  497               ctrl_st_i <= idle;
  498 
  499             when others              =>
  500               report "Unexpected control character '" & what_i &
  501                 "' while in state " & ctrl_t'image(ctrl_st_i)
  502                 severity warning;
  503               ctrl_st_i <= idle;
  504           end case;
  505 
  506         when wait_for_write =>
  507           if finish_wr_i = '1' then
  508             ctrl_st_i <= start;
  509           end if;
  510 
  511         when wait_for_read =>
  512           if finish_rd_i = '1' then
  513             ctrl_st_i <= start;
  514           end if;
  515 
  516         when others =>
  517           ctrl_st_i <= idle;
  518 
  519       end case;
  520     end if;
  521   end process control;
  522 
  523   -- purpose: Write to registers
  524   -- type   : sequential
  525   -- inputs : clk_i, grst_i
  526   -- outputs: 
  527   writer            : process (clk_i, grst_i)
  528     variable addr_i : integer := 0;
  529   begin  -- process writer
  530     if grst_i = '0' then                    -- asynchronous reset (active low)
  531       wr_st_i         <= idle;
  532       finish_wr_i     <= '0';
  533       cmd_l1_ttc_i    <= '0';
  534       cmd_l1_i2c_i    <= '0';
  535       cmd_l1_cmd_i    <= '1';
  536       cmd_rs_status_i <= '0';
  537       cmd_rs_trcfg_i  <= '0';
  538       cmd_rs_trcnt_i  <= '0';
  539       cmd_rs_buf1_i   <= '0';
  540       cmd_rs_buf2_i   <= '0';
  541       cmd_exec_i      <= '0';
  542       cmd_abort_i     <= '0';
  543       cmd_dcs_on_i    <= '0';
  544       cmd_dll_on_i    <= '0';
  545       cmd_l1_i        <= '0';
  546       cmd_glb_reset_i <= '0';
  547       cmd_fec_reset_i <= '0';
  548       cmd_rcu_reset_i <= '0';
  549       load_trcfg_i    <= '0';
  550       load_pmcfg_i    <= '0';
  551       load_afl_i      <= '0';
  552     elsif clk_i'event and clk_i = '1' then  -- rising clock edge
  553       wr_st_i         <= wr_st_i;
  554       finish_wr_i     <= '0';
  555 
  556       case wr_st_i is
  557         when idle =>
  558           if enable_wr_i = '1' then
  559             wr_st_i <= got_address;
  560           end if;
  561 
  562         when got_address =>
  563           addr_i := slv2int(ioaddr_i);
  564           wr_st_i <= got_data;
  565 
  566           -- report "Writing to " & slv2hstr(ioaddr_i) &
  567           --  ": " & slv2hstr(idata_i) severity note;
  568           case addr_i is
  569             when add_errst =>           -- errst
  570               report "Register errst is read-only" severity warning;
  571             when add_trcfg =>           -- trcfg
  572               load_trcfg_i <= '1';
  573             when add_trcnt =>           -- trcnt
  574               report "Register trcnt is read-only" severity warning;
  575             when add_lwadd =>           -- lwadd
  576               report "Register lwadd is read-only" severity warning;
  577             when add_iradd =>           -- iradd
  578               report "Register iradd is read-only" severity warning;
  579             when add_irdat =>           -- irdat
  580               report "Register irdat is read-only" severity warning;
  581             when add_pmcfg =>           -- pmcfg
  582               load_pmcfg_i <= '1';
  583             when add_chadd =>           -- chadd
  584               report "Register chadd is read-only" severity warning;
  585             when add_afl =>
  586               load_afl_i <= '1';
  587 
  588             when add_rs_status              =>  -- rs_status
  589               cmd_rs_status_i <= '1';
  590             when add_rs_trcfg               =>  -- rs_trcfg
  591               cmd_rs_trcfg_i  <= '1';
  592             when add_rs_trcnt               =>  -- rs_trcnt
  593               cmd_rs_trcnt_i  <= '1';
  594             when add_rs_buf1                =>  -- rs_buf1
  595               cmd_rs_buf1_i   <= '1';
  596             when add_rs_buf2                =>  -- rs_buf2
  597               cmd_rs_buf2_i   <= '1';
  598             when add_exec to add_exec + 127 =>  -- exec
  599               cmd_exec_i      <= '1';
  600               exec_addr_i     <= slv2int(ioaddr_i(7 downto 0));
  601             when add_abort                  =>  -- abort
  602               cmd_abort_i     <= '1';
  603             when add_dcs_on                 =>  -- dcs_on
  604               cmd_dcs_on_i    <= '1';
  605             when add_dll_on                 =>  -- dll_on
  606               cmd_dll_on_i    <= '1';
  607             when add_l1_ttc                 =>  -- l1_ttc
  608               cmd_l1_ttc_i    <= '1';
  609               cmd_l1_i2c_i    <= '0';
  610               cmd_l1_cmd_i    <= '0';
  611             when add_l1_i2c                 =>  -- l1_i2c
  612               cmd_l1_ttc_i    <= '0';
  613               cmd_l1_i2c_i    <= '1';
  614               cmd_l1_cmd_i    <= '0';
  615             when add_l1_cmd                 =>  -- l1_cmd
  616               cmd_l1_ttc_i    <= '0';
  617               cmd_l1_i2c_i    <= '0';
  618               cmd_l1_cmd_i    <= '1';
  619             when add_l1                     =>  -- l1
  620               cmd_l1_i        <= '1';
  621             when add_glb_reset              =>  -- glb_reset
  622               cmd_glb_reset_i <= '1';
  623             when add_fec_reset              =>  -- fec_reset
  624               cmd_fec_reset_i <= '1';
  625             when add_rcu_reset              =>  -- rcu_reset
  626               cmd_rcu_reset_i <= '1';
  627 
  628             when add_imem to add_imem+sz_imem-1 =>  -- IMEM
  629               imem_i(addr_i - add_imem) <= idata_i(23 downto 0);
  630             when add_pmem to add_pmem+sz_pmem-1 =>  -- PMEM
  631               pmem_i(addr_i - add_pmem) <= idata_i(9 downto 0);
  632             when add_rmem to add_rmem+sz_rmem-1 =>  -- RMEM
  633               null;
  634               -- rmem_i(addr_i - add_rmem) <= idata_i(19 downto 0);
  635             when add_acl to add_acl+sz_acl =>  -- ACL
  636               acl_i(addr_i - add_acl) <= idata_i(15 downto 0);
  637             when add_dm1l to add_dm1l+sz_dmem-1 =>  -- DM1L
  638               dm1l_i(addr_i - add_dm1l) <= idata_i(19 downto 0);
  639             when add_dm1h to add_dm1h+sz_dmem-1 =>  -- DM1H
  640               dm1h_i(addr_i - add_dm1h) <= idata_i(19 downto 0);
  641             when add_dm2l to add_dm2l+sz_dmem-1 =>  -- DM2L
  642               dm2l_i(addr_i - add_dm2l) <= idata_i(19 downto 0);
  643             when add_dm2h to add_dm2h+sz_dmem-1 =>  -- DM2H
  644               dm2h_i(addr_i - add_dm2h) <= idata_i(19 downto 0);
  645             when add_head to add_head+sz_head-1 =>  -- HEAD
  646               head_i(addr_i - add_head) <= idata_i(31 downto 0);
  647 
  648             when others =>
  649               report "Invalid address " & integer'image(addr_i)
  650                 severity warning;
  651           end case;
  652 
  653         when got_data =>
  654           cmd_rs_status_i <= '0';
  655           cmd_rs_trcfg_i  <= '0';
  656           cmd_rs_trcnt_i  <= '0';
  657           cmd_rs_buf1_i   <= '0';
  658           cmd_rs_buf2_i   <= '0';
  659           cmd_exec_i      <= '0';
  660           cmd_abort_i     <= '0';
  661           cmd_dcs_on_i    <= '0';
  662           cmd_dll_on_i    <= '0';
  663           cmd_l1_i        <= '0';
  664           cmd_glb_reset_i <= '0';
  665           cmd_fec_reset_i <= '0';
  666           cmd_rcu_reset_i <= '0';
  667           load_trcfg_i    <= '0';
  668           load_pmcfg_i    <= '0';
  669           load_afl_i      <= '0';
  670           if cmd_exec_i = '1' or exec_busy_i = '1' then
  671             wr_st_i       <= got_data;
  672           else
  673             finish_wr_i   <= '1';
  674             exec_addr_i   <= 0;
  675             wr_st_i       <= idle;
  676           end if;
  677 
  678         when others =>
  679           wr_st_i <= idle;
  680 
  681       end case;
  682     end if;
  683   end process writer;
  684 
  685   -- purpose: Read from registers
  686   -- type   : sequential
  687   -- inputs : clk_i, grst_i
  688   -- outputs: 
  689   reader              : process (clk_i, grst_i)
  690     file output_i     : text open write_mode is "/dev/stdout";  -- Input pipe
  691     variable str_i    : string(1 to 10) := (others => ' ');
  692     variable line_i   : line;
  693     variable data_i   : std_logic_vector(31 downto 0);
  694     variable addr_i   : integer         := 0;
  695     variable cnt_i    : integer         := 0;  -- Count
  696     variable cur_i    : integer         := 0;
  697     variable en_out_i : boolean         := false;
  698   begin  -- process reader
  699 
  700     if grst_i = '0' then                    -- asynchronous reset (active low)
  701       rd_st_i      <= idle;
  702       finish_rd_i  <= '0';
  703       cnt_i  := 0;
  704       cur_i  := 0;
  705       data_i := (others => '0');
  706     elsif clk_i'event and clk_i = '1' then  -- rising clock edge
  707       rd_st_i      <= rd_st_i;
  708       finish_rd_i  <= '0';
  709       enable_out_i <= '0';
  710 
  711       case rd_st_i is
  712         when idle             =>
  713           cnt_i    := 0;
  714           cur_i    := 0;
  715           data_i   := (others => '0');
  716           en_out_i := true;
  717           if enable_rd_i = '1' then
  718             rd_st_i <= got_address;
  719           end if;
  720 
  721         when got_address =>
  722           addr_i   := slv2int(ioaddr_i);
  723           cur_i    := addr_i;
  724           cnt_i    := slv2int(idata_i);
  725 
  726           case addr_i is
  727             when add_rs_status => -- rs_status
  728               report "rs_status is a command" severity warning;
  729             when add_rs_trcfg => -- rs_trcfg
  730               report "rs_trcfg is a command" severity warning;
  731             when add_rs_trcnt => -- rs_trcnt
  732               report "rs_trcnt is a command" severity warning;
  733             when add_rs_buf1 => -- rs_buf1
  734               report "rs_buf1 is a command" severity warning;
  735             when add_rs_buf2 => -- rs_buf2
  736               report "rs_buf2 is a command" severity warning;
  737             when add_exec to add_exec + 127 => -- exec
  738               report "exec is a command" severity warning;
  739             when add_abort => -- abort
  740               report "abort is a command" severity warning;
  741             when add_dcs_on                 =>  -- dcs_on
  742               report "dcs_on is a command" severity warning;
  743             when add_dll_on                 =>  -- dll_on
  744               report "dll_on is a command" severity warning;
  745             when add_l1_ttc                 =>  -- l1_ttc
  746               report "l1_ttc is a command" severity warning;
  747             when add_l1_i2c                 =>  -- l1_i2c
  748               report "l1_i2c is a command" severity warning;
  749             when add_l1_cmd                 =>  -- l1_cmd
  750               report "l1_cmd is a command" severity warning;
  751             when add_l1                     =>  -- l1
  752               report "l1 is a command" severity warning;
  753             when add_glb_reset              =>  -- glb_reset
  754               report "glb_reset is a command" severity warning;
  755             when add_fec_reset              =>  -- fec_reset
  756               report "fec_reset is a command" severity warning;
  757             when add_rcu_reset              =>  -- rcu_reset
  758               report "rcu_reset is a command" severity warning;
  759             when
  760               add_errst | add_trcfg | add_trcnt | add_lwadd |
  761               add_iradd | add_irdat | add_pmcfg | add_chadd | add_afl |
  762               add_imem to add_imem+sz_imem-1 |
  763               add_pmem to add_pmem+sz_pmem-1 |
  764               add_rmem to add_rmem+sz_rmem-1 |
  765               add_acl to add_acl+sz_acl |
  766               add_dm1l to add_dm1l+sz_dmem-1 |
  767               add_dm1h to add_dm1h+sz_dmem-1 |
  768               add_dm2l to add_dm2l+sz_dmem-1 |
  769               add_dm2h to add_dm2h+sz_dmem-1 |
  770               add_head to add_head+sz_head-1  =>
  771               en_out_i := true;
  772             when others =>
  773               report "Invalid address " & integer'image(addr_i)
  774                 severity warning;
  775           end case;
  776           if en_out_i then
  777             rd_st_i <= start;
  778           else
  779             rd_st_i <= idle;
  780           end if;
  781 
  782         when start =>
  783           -- report "Writing an s" severity note;
  784           write(line_i, 's');
  785           writeline(output_i, line_i);
  786           rd_st_i <= output;
  787 
  788         when output =>
  789           if cur_i < addr_i or cur_i >= addr_i + cnt_i then
  790             rd_st_i <= endit;
  791           else
  792             data_i   := (others => '0');
  793 
  794             case cur_i is
  795               when add_errst => -- errst
  796                 data_i(31 downto 0) :=  errst_i;
  797               when add_trcfg => -- trcfg
  798                 data_i(31 downto 0) := trcfg_i;
  799               when add_trcnt => -- trcnt
  800                 data_i(31 downto 0) := trcnt_i;
  801               when add_lwadd => -- lwadd
  802                 data_i(17 downto 0) := lwadd_i;
  803               when add_iradd => -- iradd
  804                 data_i(19 downto 0) := iradd_i;
  805               when add_irdat => -- irdat
  806                 data_i(19 downto 0) := irdat_i;
  807               when add_pmcfg => -- pmcfg
  808                 data_i(19 downto 0) :=  pmcfg_i;
  809               when add_chadd => -- chadd
  810                 data_i(23 downto 0) := chadd_i;
  811               when add_afl => -- afl
  812                 data_i(31 downto 0) := afl_i;
  813 
  814               when add_imem to add_imem+sz_imem-1 =>  -- IMEM
  815                 data_i(23 downto 0) := imem_i(cur_i - add_imem);
  816               when add_pmem to add_pmem+sz_pmem-1 =>  -- PMEM
  817                 data_i(9 downto 0) := pmem_i(cur_i - add_pmem);
  818               when add_rmem to add_rmem+sz_rmem-1 =>  -- RMEM
  819                 data_i(19 downto 0) := rmem_i(cur_i - add_rmem);
  820               when add_acl to add_acl+sz_acl =>  -- ACL
  821                 data_i(15 downto 0) := acl_i(cur_i - add_acl);
  822               when add_dm1l to add_dm1l+sz_dmem-1 =>  -- DM1L
  823                 data_i(19 downto 0) := dm1l_i(cur_i - add_dm1l);
  824               when add_dm1h to add_dm1h+sz_dmem-1 =>  -- DM1H
  825                 data_i(19 downto 0) := dm1h_i(cur_i - add_dm1h);
  826               when add_dm2l to add_dm2l+sz_dmem-1 =>  -- DM2L
  827                 data_i(19 downto 0) := dm2l_i(cur_i - add_dm2l);
  828               when add_dm2h to add_dm2h+sz_dmem-1 =>  -- DM2H
  829                 data_i(19 downto 0) := dm2h_i(cur_i - add_dm2h);
  830               when add_head to add_head+sz_head-1 =>  -- HEAD
  831                 data_i(31 downto 0) := head_i(cur_i - add_head);
  832               when others => null;
  833             end case;
  834             str_i                           := slv2hstr(data_i);
  835             -- report "Reading from " & slv2hstr(int2slv(cur_i, 20)) &
  836             --   ": " & str_i severity note;
  837             write(line_i, str_i);
  838             writeline(output_i, line_i);
  839             cur_i := cur_i + 1;
  840           end if;
  841 
  842         when endit          =>
  843           -- report "Writing an e" severity note;
  844           write(line_i, 'e');
  845           writeline(output_i, line_i);
  846           data_i := (others => '0');
  847           cur_i  := 0;
  848           addr_i := 0;
  849           cnt_i  := 0;
  850           finish_rd_i <= '1';
  851           rd_st_i     <= idle;
  852 
  853         when others =>
  854           rd_st_i <= idle;
  855       end case;
  856     end if;
  857   end process reader;
  858 
  859   -- purpose: Execute instruction memory
  860   -- type   : sequential
  861   -- inputs : clk_i, grst_i, exec_cmd_i, cmd_abort_i, exec_addr_i
  862   -- outputs: bd, cstb, write
  863   imem_exec             : process (clk_i, grst_i)
  864     variable cur_i      : integer := 0;  -- Current instruction offset
  865     variable jump_i     : integer := 0;  -- Current instruction offset
  866     variable loop_i     : integer := 0;  -- Number of loops
  867     variable iter_i     : integer := 0;  -- Current iteration
  868     variable nwait_i    : integer := 0;  -- Clock cycles to wait
  869     variable bcast_i    : std_logic;
  870     variable ack_cnt_i  : integer;
  871     variable cstb_cnt_i : integer;
  872     variable writ_i     : boolean := false;
  873     constant dont_care_i : std_logic_vector(19 downto 0) := (others => 'Z');
  874   begin  -- process imem_exec
  875 
  876     if grst_i = '0' then                    -- asynchronous reset (active low)
  877       cstb     <= 'H';
  878       writ    <= 'H';
  879       bd        <= (others => 'L');
  880       exec_st_i <= idle;
  881       iradd_i   <= (others => '0');
  882       irdat_i   <= (others => '0');
  883       cur_i := 0;
  884     elsif clk_i'event and clk_i = '1' then  -- rising clock edge
  885       if cmd_glb_reset_i = '1' or cmd_rcu_reset_i = '1' then
  886         exec_st_i <= idle;
  887       else
  888 
  889         case exec_st_i is
  890           when idle =>
  891             loop_i := 0;
  892             jump_i := 0;
  893             iter_i := 0;
  894             bd     <= (others => 'L');
  895             cstb  <= 'H';
  896             writ <= 'H';
  897 
  898             exec_busy_i   <= '0';
  899             if cmd_exec_i = '1' then
  900               exec_st_i   <= start;
  901               exec_busy_i <= '1';
  902             end if;
  903 
  904           when start =>
  905             if exec_addr_i < 0 or exec_addr_i >= sz_imem then
  906               report "Address point out of scope" severity warning;
  907               exec_st_i <= idle;
  908             else
  909               cur_i := exec_addr_i;
  910               exec_st_i <= next_instr;
  911             end if;
  912 
  913           when next_instr =>
  914             -- report "Looking at instruction @ " & integer'image(cur_i) &
  915             --   ": " & slv2hstr(imem_i(cur_i)) severity note;
  916             if cmd_abort_i = '1' then
  917               exec_st_i <= idle;
  918             elsif imem_i(cur_i)(22) = '0' then
  919               exec_st_i <= rcu_instr;
  920             else
  921               exec_st_i <= altro_instr;
  922             end if;
  923 
  924           when rcu_instr =>
  925             exec_st_i <= next_instr;
  926             if cmd_abort_i = '1' then
  927               exec_st_i <= idle;
  928             else
  929               case slv2int(imem_i(cur_i)(19 downto 16)) is
  930                 when 0     =>                    -- Loop or jump
  931                   jump_i   := slv2int(imem_i(cur_i)(7 downto 0)) - 1;
  932                   if imem_i(cur_i)(15) = '0' then  -- Jump
  933                     cur_i  := jump_i;            -- Jump to address
  934                   elsif loop_i = 0 then
  935                     loop_i := slv2int(imem_i(cur_i)(14 downto 8));
  936                     iter_i := 1;
  937                     cur_i  := jump_i;
  938                   elsif iter_i < loop_i then
  939                     iter_i := iter_i + 1;
  940                     cur_i  := jump_i;
  941                   else
  942                     loop_i := 0;
  943                     iter_i := 0;
  944                   end if;
  945                 when 1 =>                   -- Reset errst
  946                   icmd_rs_status_i <= '1';
  947                 when 2 =>                   -- Reset trcfg
  948                   icmd_rs_trcfg_i <= '1';
  949                 when 3 =>                   -- Reset trcnt
  950                   icmd_rs_trcnt_i <= '1';
  951                 when 6 =>                   -- ChRdo (not handled)
  952                   null;
  953                 when 7 =>                   -- PMREAD (not handled)
  954                   null;
  955                 when 8 =>                   -- PMWRITE (not handled)
  956                   null;
  957                 when 9 =>                   -- End of block;
  958                   exec_st_i <= idle;
  959                 when 10 =>                  -- Wait for X clock cycles
  960                   nwait_i := slv2int(imem_i(cur_i)(15 downto 0));
  961                   exec_st_i <= wait_clk;
  962                 when 11 =>
  963                   icmd_trigger_i <= '1';
  964                 when others => null;
  965               end case;
  966               cur_i := cur_i + 1;
  967             end if;
  968 
  969           when wait_clk =>
  970             if cmd_abort_i = '1' then
  971               exec_st_i <= idle;
  972             elsif nwait_i = 0 then
  973               exec_st_i <= next_instr;
  974             else
  975               nwait_i := nwait_i - 1;
  976             end if;
  977 
  978 
  979           when altro_instr =>
  980             if cmd_abort_i = '1' then
  981               exec_st_i <= idle;
  982             else
  983               -- Set address on bus
  984               iradd_i   <= (parity(imem_i(cur_i)(18 downto 0)) &
  985                             imem_i(cur_i)(18 downto 0));
  986               bcast_i := imem_i(cur_i)(18);
  987               writ_i  := imem_i(cur_i)(21) = '1';
  988               if writ_i then
  989                 writ  <= '0';
  990               else
  991                 writ  <= 'H';
  992               end if;
  993               cur_i   := cur_i + 1;
  994               exec_st_i <= altro_instr2;
  995             end if;
  996 
  997           when altro_instr2 =>
  998             if cmd_abort_i = '1' then
  999               exec_st_i <= idle;
 1000             else
 1001               -- Set data on bus
 1002               irdat_i   <= imem_i(cur_i)(19 downto 0);
 1003               cur_i := cur_i + 1;
 1004               exec_st_i <= set_bus;
 1005             end if;
 1006 
 1007           when set_bus                       =>
 1008             if cmd_abort_i = '1' then
 1009               exec_st_i <= idle;
 1010             else
 1011               if writ_i then
 1012                 bd      <= iradd_i & irdat_i;
 1013               else
 1014                 bd      <= iradd_i & dont_care_i;
 1015               end if;
 1016               exec_st_i <= strobe;
 1017             end if;
 1018 
 1019           when strobe =>
 1020             if cmd_abort_i = '1' then
 1021               exec_st_i   <= idle;
 1022             else
 1023               -- Assert the control strobe
 1024               cstb       <= '0';
 1025               timeout_i   <= '0';
 1026               if bcast_i = '1' then
 1027                 cstb_cnt_i := 4;
 1028                 exec_st_i <= wait_strobe;
 1029               else
 1030                 ack_cnt_i  := 32;
 1031                 exec_st_i <= wait_ack;
 1032               end if;
 1033             end if;
 1034 
 1035           when wait_strobe =>
 1036             if cmd_abort_i = '1' then
 1037               exec_st_i <= idle;
 1038             elsif cstb_cnt_i = 0 then
 1039               cstb     <= 'H';
 1040               writ    <= 'H';
 1041               exec_st_i <= next_instr;
 1042             else
 1043               cstb_cnt_i := cstb_cnt_i - 1;
 1044             end if;
 1045 
 1046           when wait_ack                   =>
 1047             if cmd_abort_i = '1' then
 1048               exec_st_i        <= idle;
 1049             elsif eror = '0' then
 1050               exec_st_i        <= idle;
 1051             elsif ackn = '0' then
 1052               cstb             <= 'H';
 1053               writ             <= 'H';
 1054               bd(39 downto 20) <= (others => 'L');
 1055               exec_st_i        <= take_data;
 1056             -- elsif ack_cnt_i = 16 then  -- Temporary
 1057               -- cstb      <= 'H';
 1058               -- writ      <= 'H';
 1059               -- bd        <= (others => 'L');
 1060               -- exec_st_i <= take_data;
 1061             elsif ack_cnt_i = 0 then
 1062               report "Acknowledge timeout " severity WARNING;
 1063               cstb             <= 'H';
 1064               writ             <= 'H';
 1065               timeout_i        <= '1';
 1066               exec_st_i        <= next_instr;
 1067             else
 1068               ack_cnt_i := ack_cnt_i - 1;
 1069             end if;
 1070 
 1071           when take_data =>
 1072             -- report "data on bus: " & slv2hstr(bd(19 downto 0)) &
 1073             --   " rmem_0=" & slv2hstr(rmem_i(0)) severity note;
 1074             rmem_i(0) <= bd(19 downto 0);
 1075             if ackn /= '0' then
 1076               exec_st_i <= next_instr;
 1077             end if;
 1078 
 1079           when others => null;
 1080         end case;
 1081       end if;
 1082     end if;
 1083   end process imem_exec;
 1084 
 1085 
 1086   -- purpose: Handle register trcfg_i
 1087   -- type   : sequential
 1088   -- inputs : clk_i, grst_i
 1089   -- outputs: 
 1090   registers           : process (clk_i, grst_i)
 1091     variable l1_cnt_i  : integer range 0 to 2**16 - 1;
 1092     variable l2_cnt_i  : integer range 0 to 2**16 - 1;
 1093     variable rst_cnt_i : integer := 0;
 1094   begin  -- process trcfg_proc
 1095     if grst_i = '0' then                    -- asynchronous reset (active low)
 1096       trcfg_i <= (others => '0');
 1097       pmcfg_i <= (others => '0');
 1098       l1_cnt_i                   := 0;
 1099       l2_cnt_i                   := 0;
 1100       grst  <= '0';
 1101     elsif clk_i'event and clk_i = '1' then  -- rising clock edge
 1102 
 1103       if (icmd_rs_trcfg_i = '1' or
 1104           cmd_rs_trcfg_i = '1' or
 1105           cmd_rcu_reset_i = '1' or
 1106           cmd_glb_reset_i = '1') then
 1107         trcfg_i <= (others => '0');
 1108       elsif load_trcfg_i = '1' then
 1109         trcfg_i <= idata_i;
 1110       end if;
 1111 
 1112       if (cmd_rcu_reset_i = '1' or
 1113           cmd_glb_reset_i = '1') then
 1114         pmcfg_i <= (others => '0');
 1115       elsif load_pmcfg_i = '1'  then
 1116         pmcfg_i <= idata_i(19 downto 0);
 1117       end if;
 1118 
 1119       if (cmd_rcu_reset_i = '1' or
 1120           cmd_glb_reset_i = '1') then
 1121         afl_i <= (others => '0');
 1122       elsif load_afl_i = '1'  then
 1123         afl_i <= idata_i(31 downto 0);
 1124       end if;
 1125 
 1126       if (cmd_rs_status_i = '1' or
 1127           icmd_rs_status_i = '1' or
 1128           cmd_rcu_reset_i = '1' or
 1129           cmd_glb_reset_i = '1') then
 1130         errst_i              <= (others => '0');
 1131       else
 1132         errst_i(31)          <= exec_busy_i;
 1133         errst_i(30 downto 4) <= (others => '0');
 1134         if eror = '0' then
 1135           errst_i(3)         <= '1';
 1136         else
 1137           errst_i(3)         <= '0';
 1138         end if;
 1139         if cmd_abort_i = '1' then
 1140           errst_i(1)         <= '1';
 1141         else
 1142           errst_i(1)         <= '0';
 1143         end if;
 1144         if timeout_i = '1' then
 1145           errst_i(2)         <= '1';
 1146         else
 1147           errst_i(2)         <= '0';
 1148         end if;
 1149         errst_i(0)           <= '0';
 1150       end if;
 1151 
 1152       l1_ii <= l1_i;
 1153       l2_ii <= l2_i;
 1154       if (cmd_rs_trcnt_i = '1' or
 1155           icmd_rs_trcnt_i = '1' or
 1156           cmd_rcu_reset_i = '1' or
 1157           cmd_glb_reset_i = '1') then
 1158         l1_cnt_i := 0;
 1159         l2_cnt_i := 0;
 1160       elsif l1_i = '0' and l1_ii = '1' then
 1161         l1_cnt_i := l1_cnt_i + 1;
 1162       elsif l2_i = '0' and l2_ii = '1' then
 1163         l2_cnt_i := l2_cnt_i + 1;
 1164       end if;
 1165       trcnt_i <= int2slv(l2_cnt_i, 16) & int2slv(l1_cnt_i, 16);
 1166 
 1167       -- Keep the fec reset down for at least 200 ns;
 1168       if (cmd_glb_reset_i = '1' or cmd_fec_reset_i = '1') then
 1169         rst_cnt_i := 8;
 1170         grst <= '0';
 1171       elsif rst_cnt_i > 0 then
 1172         rst_cnt_i := rst_cnt_i - 1;
 1173         grst <= '0';
 1174       else
 1175         grst <= '1';
 1176       end if;
 1177 
 1178     end if;
 1179   end process registers;
 1180 
 1181   -- purpose: Make triggers
 1182   -- type   : sequential
 1183   -- inputs : clk_i, grst_i
 1184   -- outputs: 
 1185   triggers             : process (clk_i, grst_i)
 1186     variable l0_dur_i  : integer := 0;
 1187     variable l1_dur_i  : integer := 0;
 1188     variable l2_dur_i  : integer := 0;
 1189     variable l1_wait_i : integer := 0;
 1190     variable l2_wait_i : integer := 0;
 1191   begin  -- process triggers 
 1192     if grst_i = '0' then                    -- asynchronous reset (active low)
 1193       trg_st_i <= idle;
 1194       l0_i     <= '0';
 1195       l1_i     <= '1';
 1196       l2_i     <= '1';
 1197     elsif clk_i'event and clk_i = '1' then  -- rising clock edge
 1198       trg_st_i <= trg_st_i;
 1199 
 1200       case trg_st_i is
 1201         when idle =>
 1202           l0_i <= '0';
 1203           l1_i <= '1';
 1204           l2_i <= '1';
 1205           if ((cmd_l1_i = '1' or icmd_trigger_i = '1') and
 1206               cmd_l1_cmd_i = '1' and trcfg_i(16 downto 15) = "10") then
 1207             trg_st_i <= gen_l0;
 1208             l0_dur_i := 8;
 1209             l0_i <= '1';
 1210           end if;
 1211 
 1212         when gen_l0 =>
 1213           if l0_dur_i = 0 then
 1214             l1_wait_i := 5.5 us / 25 ns - 8;
 1215             l0_i     <= '0';
 1216             trg_st_i <= wait_to_l2;
 1217           else
 1218             l0_i     <= '1';
 1219             l0_dur_i  := l0_dur_i - 1;
 1220           end if;
 1221 
 1222         when wait_to_l1 =>
 1223           if l2_wait_i = 0 then
 1224             trg_st_i <= gen_l1;
 1225           else
 1226             l1_wait_i := l1_wait_i - 1;
 1227           end if;
 1228 
 1229         when gen_l1 =>
 1230           if l1_dur_i = 0 then
 1231             l2_wait_i := slv2int(trcfg_i(13 downto 0));
 1232             l1_i     <= '1';
 1233             trg_st_i <= wait_to_l2;
 1234           else
 1235             l1_i     <= '0';
 1236             l1_dur_i  := l1_dur_i - 1;
 1237           end if;
 1238 
 1239         when wait_to_l2 =>
 1240           if l2_wait_i = 0 then
 1241             trg_st_i <= gen_l2;
 1242           else
 1243             l2_wait_i := l2_wait_i - 1;
 1244           end if;
 1245 
 1246         when gen_l2 =>
 1247           if l2_dur_i = 0 then
 1248             l2_i <= '1';
 1249             trg_st_i <= idle;
 1250           else
 1251             l2_i <= '0';
 1252             l2_dur_i := l2_dur_i - 1;
 1253           end if;
 1254 
 1255         when others => null;
 1256       end case;
 1257     end if;
 1258   end process triggers ;
 1259 
 1260   -- Reset
 1261   reset_it : entity rcu_model.reseter port map (rstb => grst_i);
 1262 
 1263   -- 40 Mhz
 1264   rclk_clocker : entity rcu_model.clocker
 1265     generic map (PERIOD => 1 sec / 40000000)
 1266     port map (clk       => clk_i);
 1267 
 1268   -- 10 MHz  
 1269   sclk_clocker : entity rcu_model.clocker
 1270     generic map (PERIOD => 1 sec / 10000000)
 1271     port map (clk       => sclk_i);
 1272 
 1273   -- 5 MHz  
 1274   scl_clocker : entity rcu_model.clocker
 1275     generic map (PERIOD => 1 sec / 5000000)
 1276     port map (clk       => scl);
 1277 
 1278 end architecture pipe_stim;
 1279 
 1280 ------------------------------------------------------------------------------
 1281 -- 
 1282 -- EOF
 1283 --
 1284 

This page was generated using GHDL 0.26 (20070408) [Sokcho edition], a program written by Tristan Gingold