diff options
author | Bert Lange <b.lange@fzd.de> | 2010-08-13 15:01:22 +0200 |
---|---|---|
committer | Bert Lange <b.lange@fzd.de> | 2010-08-13 15:01:22 +0200 |
commit | 14a33e92c5509b217260dc672881de4fe93ae432 (patch) | |
tree | d4efe0dafde81443bb30a2e7d0591047fa7ad70f | |
parent | 9df643231624cfbd2abd3aeea9f9679880c5dac8 (diff) | |
download | zpu-14a33e92c5509b217260dc672881de4fe93ae432.zip zpu-14a33e92c5509b217260dc672881de4fe93ae432.tar.gz |
add: to project
-rw-r--r-- | s3estarter/rtl_tb/phy.vhd | 666 | ||||
-rw-r--r-- | techmap/rtl/syncram.vhd | 216 |
2 files changed, 882 insertions, 0 deletions
diff --git a/s3estarter/rtl_tb/phy.vhd b/s3estarter/rtl_tb/phy.vhd new file mode 100644 index 0000000..9084451 --- /dev/null +++ b/s3estarter/rtl_tb/phy.vhd @@ -0,0 +1,666 @@ +------------------------------------------------------------------------------ +-- This file is a part of the GRLIB VHDL IP LIBRARY +-- Copyright (C) 2003 - 2008, Gaisler Research +-- Copyright (C) 2008 - 2010, Aeroflex Gaisler +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +---------------------------------------------------------------------------- +-- Entity: phy +-- File: phy.vhd +-- Description: Simulation model of an Ethernet PHY +-- Author: Marko Isomaki +------------------------------------------------------------------------------ + +-- pragma translate_off + +library ieee; +library grlib; + +use ieee.std_logic_1164.all; +use grlib.stdlib.all; + +entity phy is + generic( + address : integer range 0 to 31 := 0; + extended_regs : integer range 0 to 1 := 1; + aneg : integer range 0 to 1 := 1; + base100_t4 : integer range 0 to 1 := 0; + base100_x_fd : integer range 0 to 1 := 1; + base100_x_hd : integer range 0 to 1 := 1; + fd_10 : integer range 0 to 1 := 1; + hd_10 : integer range 0 to 1 := 1; + base100_t2_fd : integer range 0 to 1 := 1; + base100_t2_hd : integer range 0 to 1 := 1; + base1000_x_fd : integer range 0 to 1 := 0; + base1000_x_hd : integer range 0 to 1 := 0; + base1000_t_fd : integer range 0 to 1 := 1; + base1000_t_hd : integer range 0 to 1 := 1; + rmii : integer range 0 to 1 := 0 + ); + port( + simulation_run : in boolean := true; + rstn : in std_logic; + mdio : inout std_logic; + tx_clk : out std_logic; + rx_clk : out std_logic; + rxd : out std_logic_vector(7 downto 0); + rx_dv : out std_logic; + rx_er : out std_logic; + rx_col : out std_logic; + rx_crs : out std_logic; + txd : in std_logic_vector(7 downto 0); + tx_en : in std_logic; + tx_er : in std_logic; + mdc : in std_logic; + gtx_clk : in std_logic + ); +end; + +architecture behavioral of phy is + type mdio_state_type is (idle, start_of_frame, start_of_frame2, op, phyad, regad, + ta, rdata, wdata); + + type ctrl_reg_type is record + reset : std_ulogic; + loopback : std_ulogic; + speedsel : std_logic_vector(1 downto 0); + anegen : std_ulogic; + powerdown : std_ulogic; + isolate : std_ulogic; + restartaneg : std_ulogic; + duplexmode : std_ulogic; + coltest : std_ulogic; + end record; + + type status_reg_type is record + base100_t4 : std_ulogic; + base100_x_fd : std_ulogic; + base100_x_hd : std_ulogic; + fd_10 : std_ulogic; + hd_10 : std_ulogic; + base100_t2_fd : std_ulogic; + base100_t2_hd : std_ulogic; + extstat : std_ulogic; + mfpreamblesup : std_ulogic; + anegcmpt : std_ulogic; + remfault : std_ulogic; + anegability : std_ulogic; + linkstat : std_ulogic; + jabdetect : std_ulogic; + extcap : std_ulogic; + end record; + + type aneg_ab_type is record + next_page : std_ulogic; + remote_fault : std_ulogic; + tech_ability : std_logic_vector(7 downto 0); + selector : std_logic_vector(4 downto 0); + end record; + + type aneg_exp_type is record + par_detct_flt : std_ulogic; + lp_np_able : std_ulogic; + np_able : std_ulogic; + page_rx : std_ulogic; + lp_aneg_able : std_ulogic; + end record; + + type aneg_nextpage_type is record + next_page : std_ulogic; + message_page : std_ulogic; + ack2 : std_ulogic; + toggle : std_ulogic; + message : std_logic_vector(10 downto 0); + end record; + + type mst_slv_ctrl_type is record + tmode : std_logic_vector(2 downto 0); + manualcfgen : std_ulogic; + cfgval : std_ulogic; + porttype : std_ulogic; + base1000_t_fd : std_ulogic; + base1000_t_hd : std_ulogic; + end record; + + type mst_slv_status_type is record + cfgfault : std_ulogic; + cfgres : std_ulogic; + locrxstate : std_ulogic; + remrxstate : std_ulogic; + lpbase1000_t_fd : std_ulogic; + lpbase1000_t_hd : std_ulogic; + idlerrcnt : std_logic_vector(7 downto 0); + end record; + + type extended_status_reg_type is record + base1000_x_fd : std_ulogic; + base1000_x_hd : std_ulogic; + base1000_t_fd : std_ulogic; + base1000_t_hd : std_ulogic; + end record; + + type reg_type is record + state : mdio_state_type; + cnt : integer; + op : std_logic_vector(1 downto 0); + phyad : std_logic_vector(4 downto 0); + regad : std_logic_vector(4 downto 0); + wr : std_ulogic; + regtmp : std_logic_vector(15 downto 0); + -- MII management registers + ctrl : ctrl_reg_type; + status : status_reg_type; + anegadv : aneg_ab_type; + aneglp : aneg_ab_type; + anegexp : aneg_exp_type; + anegnptx : aneg_nextpage_type; + anegnplp : aneg_nextpage_type; + mstslvctrl : mst_slv_ctrl_type; + mstslvstat : mst_slv_status_type; + extstatus : extended_status_reg_type; + rstcnt : integer; + anegcnt : integer; + end record; + + signal r, rin : reg_type; + signal int_clk : std_ulogic := '0'; + signal clkslow : std_ulogic := '0'; + signal rcnt : integer; + signal anegact : std_ulogic; +begin + --mdio signal pull-up + int_clk <= not int_clk after 10 ns when rmii = 1 and simulation_run else + not int_clk after 4 ns when r.ctrl.speedsel = "01" and simulation_run else + not int_clk after 20 ns when r.ctrl.speedsel = "10" and simulation_run else + not int_clk after 200 ns when r.ctrl.speedsel = "00" and simulation_run ; + + clkslow <= not clkslow after 20 ns when r.ctrl.speedsel = "10" and simulation_run else + not clkslow after 200 ns when simulation_run; + +-- rstdelay : process +-- begin +-- loop +-- rstd <= '0'; +-- while r.ctrl.reset /= '1' loop +-- wait on r.ctrl.reset; +-- end loop; +-- rstd <= '1'; +-- while rstn = '0' loop +-- wait on rstn; +-- end loop; +-- wait on rstn for 3 us; +-- rstd <= '0'; +-- wait on rstn until r.ctrl.reset = '0' for 5 us; +-- end loop; +-- end process; + + anegproc : process is + begin + loop + anegact <= '0'; + while rstn /= '1' loop + wait on rstn; + end loop; + while rstn = '1' loop + if r.ctrl.anegen = '0' then + anegact <= '0'; + wait on rstn, r.ctrl.anegen, r.ctrl.restartaneg; + else + if r.ctrl.restartaneg = '1' then + anegact <= '1'; + wait on rstn, r.ctrl.restartaneg, r.ctrl.anegen for 2 us; + anegact <= '0'; + wait on rstn, r.ctrl.anegen until r.ctrl.restartaneg = '0'; + if (rstn and r.ctrl.anegen) = '1' then + wait on rstn, r.ctrl.anegen, r.ctrl.restartaneg; + end if; + else + anegact <= '0'; + wait on rstn, r.ctrl.restartaneg, r.ctrl.anegen; + end if; + end if; + end loop; + end loop; + end process; + + mdiocomb : process(r, anegact, mdio) is + variable v : reg_type; + begin + v := r; + if anegact = '0' then + v.ctrl.restartaneg := '0'; + end if; + case r.state is + when idle => + mdio <= 'Z'; + if to_X01(mdio) = '1' then + v.cnt := v.cnt + 1; + if v.cnt = 31 then + v.state := start_of_frame; v.cnt := 0; + end if; + else + v.cnt := 0; + end if; + when start_of_frame => + if to_X01(mdio) = '0' then + v.state := start_of_frame2; + elsif to_X01(mdio) /= '1' then + v.state := idle; + end if; + when start_of_frame2 => + if to_X01(mdio) = '1' then + v.state := op; + else + v.state := idle; + end if; + when op => + v.cnt := v.cnt + 1; + v.op := r.op(0) & to_X01(mdio); + if r.cnt = 1 then + if (v.op = "01") or (v.op = "10") then + v.state := phyad; v.cnt := 0; + else + v.state := idle; v.cnt := 0; + end if; + end if; + when phyad => + v.phyad := r.phyad(3 downto 0) & to_X01(mdio); + v.cnt := v.cnt + 1; + if r.cnt = 4 then + v.state := regad; v.cnt := 0; + end if; + when regad => + v.regad := r.regad(3 downto 0) & to_X01(mdio); + v.cnt := v.cnt + 1; + if r.cnt = 4 then + v.cnt := 0; + if conv_integer(r.phyad) = address then + v.state := ta; + else + v.state := idle; + end if; + end if; + when ta => + v.cnt := r.cnt + 1; + if r.cnt = 0 then + if (r.op = "01") and to_X01(mdio) /= '1' then + v.cnt := 0; v.state := idle; + end if; + else + if r.op = "10" then + mdio <= '0'; v.cnt := 0; v.state := rdata; + case r.regad is + when "00000" => --ctrl (basic) + v.regtmp := r.ctrl.reset & r.ctrl.loopback & + r.ctrl.speedsel(1) & r.ctrl.anegen & r.ctrl.powerdown & + r.ctrl.isolate & r.ctrl.restartaneg & r.ctrl.duplexmode & + r.ctrl.coltest & r.ctrl.speedsel(0) & "000000"; + when "00001" => --statuc (basic) + v.regtmp := r.status.base100_t4 & r.status.base100_x_fd & + r.status.base100_x_hd & r.status.fd_10 & r.status.hd_10 & + r.status.base100_t2_fd & r.status.base100_t2_hd & + r.status.extstat & '0' & r.status.mfpreamblesup & + r.status.anegcmpt & r.status.remfault & r.status.anegability & + r.status.linkstat & r.status.jabdetect & r.status.extcap; + when "00010" => --PHY ID (extended) + if extended_regs = 1 then + v.regtmp := X"0007"; + else + v.cnt := 0; v.state := idle; + end if; + when "00011" => --PHY ID (extended) + if extended_regs = 1 then + v.regtmp := X"C0A3"; + else + v.cnt := 0; v.state := idle; + end if; + when "00100" => --Auto-neg adv. (extended) + if extended_regs = 1 then + v.regtmp := r.anegadv.next_page & '0' & r.anegadv.remote_fault & + r.anegadv.tech_ability & r.anegadv.selector; + else + v.cnt := 0; v.state := idle; + end if; + when "00101" => --Auto-neg link partner ability (extended) + if extended_regs = 1 then + v.regtmp := r.aneglp.next_page & '0' & r.aneglp.remote_fault & + r.aneglp.tech_ability & r.aneglp.selector; + else + v.cnt := 0; v.state := idle; + end if; + when "00110" => --Auto-neg expansion (extended) + if extended_regs = 1 then + v.regtmp := "00000000000" & r.anegexp.par_detct_flt & + r.anegexp.lp_np_able & r.anegexp.np_able & r.anegexp.page_rx & + r.anegexp.lp_aneg_able; + else + v.cnt := 0; v.state := idle; + end if; + when "00111" => --Auto-neg next page (extended) + if extended_regs = 1 then + v.regtmp := r.anegnptx.next_page & '0' & r.anegnptx.message_page & + r.anegnptx.ack2 & r.anegnptx.toggle & r.anegnptx.message; + else + v.cnt := 0; v.state := idle; + end if; + when "01000" => --Auto-neg link partner received next page (extended) + if extended_regs = 1 then + v.regtmp := r.anegnplp.next_page & '0' & r.anegnplp.message_page & + r.anegnplp.ack2 & r.anegnplp.toggle & r.anegnplp.message; + else + v.cnt := 0; v.state := idle; + end if; + when "01001" => --Master-slave control (extended) + if extended_regs = 1 then + v.regtmp := r.mstslvctrl.tmode & r.mstslvctrl.manualcfgen & + r.mstslvctrl.cfgval & r.mstslvctrl.porttype & + r.mstslvctrl.base1000_t_fd & r.mstslvctrl.base1000_t_hd & + "00000000"; + else + v.cnt := 0; v.state := idle; + end if; + when "01010" => --Master-slave status (extended) + if extended_regs = 1 then + v.regtmp := r.mstslvstat.cfgfault & r.mstslvstat.cfgres & + r.mstslvstat.locrxstate & r.mstslvstat.remrxstate & + r.mstslvstat.lpbase1000_t_fd & r.mstslvstat.lpbase1000_t_hd & + "00" & r.mstslvstat.idlerrcnt; + else + v.cnt := 0; v.state := idle; + end if; + when "01111" => + if (base1000_x_fd = 1) or (base1000_x_hd = 1) or + (base1000_t_fd = 1) or (base1000_t_hd = 1) then + v.regtmp := r.extstatus.base1000_x_fd & + r.extstatus.base1000_x_hd & + r.extstatus.base1000_t_fd & + r.extstatus.base1000_t_hd & X"000"; + else + v.regtmp := (others => '0'); + end if; + when others => + --PHY shall not drive MDIO when unimplemented registers + --are accessed + v.cnt := 0; v.state := idle; + v.regtmp := (others => '0'); + end case; + if r.ctrl.reset = '1' then + if r.regad = "00000" then + v.regtmp := X"8000"; + else + v.regtmp := X"0000"; + end if; + end if; + else + if to_X01(mdio) /= '0'then + v.cnt := 0; v.state := idle; + else + v.cnt := 0; v.state := wdata; + end if; + end if; + end if; + when rdata => + v.cnt := r.cnt + 1; + mdio <= r.regtmp(15-r.cnt); + if r.cnt = 15 then + v.state := idle; v.cnt := 0; + end if; + when wdata => + v.cnt := r.cnt + 1; + v.regtmp := r.regtmp(14 downto 0) & to_X01(mdio); + if r.cnt = 15 then + v.state := idle; v.cnt := 0; + if r.ctrl.reset = '0' then + case r.regad is + when "00000" => + v.ctrl.reset := v.regtmp(15); + v.ctrl.loopback := v.regtmp(14); + v.ctrl.speedsel(1) := v.regtmp(13); + v.ctrl.anegen := v.regtmp(12); + v.ctrl.powerdown := v.regtmp(11); + v.ctrl.isolate := v.regtmp(10); + v.ctrl.restartaneg := v.regtmp(9); + v.ctrl.duplexmode := v.regtmp(8); + v.ctrl.coltest := v.regtmp(7); + v.ctrl.speedsel(0) := v.regtmp(6); + when "00100" => + if extended_regs = 1 then + v.anegadv.remote_fault := r.regtmp(13); + v.anegadv.tech_ability := r.regtmp(12 downto 5); + v.anegadv.selector := r.regtmp(4 downto 0); + end if; + when "00111" => + if extended_regs = 1 then + v.anegnptx.next_page := r.regtmp(15); + v.anegnptx.message_page := r.regtmp(13); + v.anegnptx.ack2 := r.regtmp(12); + v.anegnptx.message := r.regtmp(10 downto 0); + end if; + when "01001" => + if extended_regs = 1 then + v.mstslvctrl.tmode := r.regtmp(15 downto 13); + v.mstslvctrl.manualcfgen := r.regtmp(12); + v.mstslvctrl.cfgval := r.regtmp(11); + v.mstslvctrl.porttype := r.regtmp(10); + v.mstslvctrl.base1000_t_fd := r.regtmp(9); + v.mstslvctrl.base1000_t_hd := r.regtmp(8); + end if; + when others => --no writable bits for other regs + null; + end case; + end if; + end if; + when others => + null; + end case; + if r.rstcnt > 19 then + v.ctrl.reset := '0'; v.rstcnt := 0; + else + v.rstcnt := r.rstcnt + 1; + end if; + if (v.ctrl.reset and not r.ctrl.reset) = '1' then + v.rstcnt := 0; + end if; + if r.ctrl.anegen = '1' then + if r.anegcnt < 10 then + v.anegcnt := r.anegcnt + 1; + else + v.status.anegcmpt := '1'; + if (base1000_x_fd = 1) or (base1000_x_hd = 1) or + (r.mstslvctrl.base1000_t_fd = '1') or + (r.mstslvctrl.base1000_t_hd = '1') then + v.ctrl.speedsel(1 downto 0) := "01"; + elsif (r.anegadv.tech_ability(4) = '1') or + (r.anegadv.tech_ability(3) = '1') or + (r.anegadv.tech_ability(2) = '1') or + (base100_t2_fd = 1) or (base100_t2_hd = 1) then + v.ctrl.speedsel(1 downto 0) := "10"; + else + v.ctrl.speedsel(1 downto 0) := "00"; + end if; + if ((base1000_x_fd = 1) or (r.mstslvctrl.base1000_t_fd = '1')) or + (((base100_t2_fd = 1) or (r.anegadv.tech_ability(3) = '1')) and + (r.mstslvctrl.base1000_t_hd = '0') and (base1000_x_hd = 0)) or + ((r.anegadv.tech_ability(1) = '1') and (base100_t2_hd = 0) and + (r.anegadv.tech_ability(4) = '0') and + (r.anegadv.tech_ability(2) = '0')) then + v.ctrl.duplexmode := '1'; + else + v.ctrl.duplexmode := '0'; + end if; + end if; + end if; + if r.ctrl.restartaneg = '1' then + v.anegcnt := 0; + v.status.anegcmpt := '0'; + v.ctrl.restartaneg := '0'; + end if; + rin <= v; + end process; + + reg : process(rstn, mdc, rin,r ) is + begin + if rising_edge(mdc) then + r <= rin; + end if; +-- -- RESET DELAY +-- if rstd = '1' then +-- r.ctrl.reset <= '1'; +-- else +-- r.ctrl.reset <= '0'; +-- end if; + + -- RESET + if (r.ctrl.reset or not rstn) = '1' then + r.ctrl.loopback <= '1'; r.anegcnt <= 0; + if (base1000_x_hd = 1) or (base1000_x_fd = 1) or (base1000_t_hd = 1) or + (base1000_t_fd = 1) then + r.ctrl.speedsel <= "01"; + elsif (base100_x_hd = 1) or (base100_t2_hd = 1) or (base100_x_fd = 1) or + (base100_t2_fd = 1) or (base100_t4 = 1) then + r.ctrl.speedsel <= "10"; + else + r.ctrl.speedsel <= "00"; + end if; + + r.ctrl.anegen <= conv_std_logic(aneg = 1); + r.ctrl.powerdown <= '0'; + r.ctrl.isolate <= '0'; + r.ctrl.restartaneg <= '0'; + if (base100_x_hd = 0) and (hd_10 = 0) and (base100_t2_hd = 0) and + (base1000_x_hd = 0) and (base1000_t_hd = 0) then + r.ctrl.duplexmode <= '1'; + else + r.ctrl.duplexmode <= '0'; + end if; + r.ctrl.coltest <= '0'; + + r.status.base100_t4 <= conv_std_logic(base100_t4 = 1); + r.status.base100_x_fd <= conv_std_logic(base100_x_fd = 1); + r.status.base100_x_hd <= conv_std_logic(base100_x_hd = 1); + r.status.fd_10 <= conv_std_logic(fd_10 = 1); + r.status.hd_10 <= conv_std_logic(hd_10 = 1); + r.status.base100_t2_fd <= conv_std_logic(base100_t2_fd = 1); + r.status.base100_t2_hd <= conv_std_logic(base100_t2_hd = 1); + r.status.extstat <= conv_std_logic((base1000_x_fd = 1) or + (base1000_x_hd = 1) or + (base1000_t_fd = 1) or + (base1000_t_hd = 1)); + r.status.mfpreamblesup <= '0'; + r.status.anegcmpt <= '0'; + r.status.remfault <= '0'; + r.status.anegability <= conv_std_logic(aneg = 1); + r.status.linkstat <= '0'; + r.status.jabdetect <= '0'; + r.status.extcap <= conv_std_logic(extended_regs = 1); + + r.anegadv.next_page <= '0'; + r.anegadv.remote_fault <= '0'; + r.anegadv.tech_ability <= "000" & conv_std_logic(base100_t4 = 1) & + conv_std_logic(base100_x_fd = 1) & conv_std_logic(base100_x_hd = 1) & + conv_std_logic(fd_10 = 1) & conv_std_logic(hd_10 = 1); + r.anegadv.selector <= "00001"; + + r.aneglp.next_page <= '0'; + r.aneglp.remote_fault <= '0'; + r.aneglp.tech_ability <= "000" & conv_std_logic(base100_t4 = 1) & + conv_std_logic(base100_x_fd = 1) & conv_std_logic(base100_x_hd = 1) & + conv_std_logic(fd_10 = 1) & conv_std_logic(hd_10 = 1); + r.aneglp.selector <= "00001"; + + r.anegexp.par_detct_flt <= '0'; + r.anegexp.lp_np_able <= '0'; + r.anegexp.np_able <= '0'; + r.anegexp.page_rx <= '0'; + r.anegexp.lp_aneg_able <= '0'; + + r.anegnptx.next_page <= '0'; + r.anegnptx.message_page <= '1'; + r.anegnptx.ack2 <= '0'; + r.anegnptx.toggle <= '0'; + r.anegnptx.message <= "00000000001"; + + r.anegnplp.next_page <= '0'; + r.anegnplp.message_page <= '1'; + r.anegnplp.ack2 <= '0'; + r.anegnplp.toggle <= '0'; + r.anegnplp.message <= "00000000001"; + + r.mstslvctrl.tmode <= (others => '0'); + r.mstslvctrl.manualcfgen <= '0'; + r.mstslvctrl.cfgval <= '0'; + r.mstslvctrl.porttype <= '0'; + r.mstslvctrl.base1000_t_fd <= conv_std_logic(base1000_t_fd = 1); + r.mstslvctrl.base1000_t_hd <= conv_std_logic(base1000_t_fd = 1); + + r.mstslvstat.cfgfault <= '0'; + r.mstslvstat.cfgres <= '1'; + r.mstslvstat.locrxstate <= '1'; + r.mstslvstat.remrxstate <= '1'; + r.mstslvstat.lpbase1000_t_fd <= conv_std_logic(base1000_t_fd = 1); + r.mstslvstat.lpbase1000_t_hd <= conv_std_logic(base1000_t_fd = 1); + r.mstslvstat.idlerrcnt <= (others => '0'); + + r.extstatus.base1000_x_fd <= conv_std_logic(base1000_x_fd = 1); + r.extstatus.base1000_x_hd <= conv_std_logic(base1000_x_hd = 1); + r.extstatus.base1000_t_fd <= conv_std_logic(base1000_t_fd = 1); + r.extstatus.base1000_t_hd <= conv_std_logic(base1000_t_hd = 1); + + end if; + + if rstn = '0' then + r.cnt <= 0; r.state <= idle; r.rstcnt <= 0; + r.ctrl.reset <= '1'; + end if; + end process; + + + loopback_sel : process(r.ctrl.loopback, int_clk, gtx_clk, r.ctrl.speedsel, txd, tx_en, tx_er, clkslow) is + begin + if r.ctrl.loopback = '1' then + if rmii = 0 then + rx_col <= '0'; rx_crs <= tx_en; rx_dv <= tx_en; rx_er <= tx_er; + rxd <= txd; + if r.ctrl.speedsel /= "01" then + rx_clk <= int_clk; tx_clk <= int_clk; + else + rx_clk <= gtx_clk; tx_clk <= clkslow; + end if; + else + rx_dv <= '1'; rx_er <= '1'; --unused should not affect anything + rx_col <= '0'; rx_crs <= tx_en; + if tx_en = '0' then + rxd(1 downto 0) <= "00"; + else + rxd(1 downto 0) <= txd(1 downto 0); + end if; + rx_clk <= '0'; tx_clk <= '0'; + end if; + else + rx_col <= '0'; rx_crs <= '0'; rx_dv <= '0'; rx_er <= '0'; + rxd <= (others => '0'); + if rmii = 0 then + if r.ctrl.speedsel /= "01" then + rx_clk <= int_clk; tx_clk <= int_clk after 3 ns; + else + rx_clk <= gtx_clk; tx_clk <= clkslow; + end if; + else + rx_clk <= int_clk; tx_clk <= int_clk after 3 ns; + end if; + end if; + end process; +end; +-- pragma translate_on diff --git a/techmap/rtl/syncram.vhd b/techmap/rtl/syncram.vhd new file mode 100644 index 0000000..4baacc5 --- /dev/null +++ b/techmap/rtl/syncram.vhd @@ -0,0 +1,216 @@ +------------------------------------------------------------------------------ +-- This file is a part of the GRLIB VHDL IP LIBRARY +-- Copyright (C) 2003 - 2008, Gaisler Research +-- Copyright (C) 2008 - 2010, Aeroflex Gaisler +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program; if not, write to the Free Software +-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +----------------------------------------------------------------------------- +-- Entity: syncram +-- File: syncram.vhd +-- Author: Jiri Gaisler - Gaisler Research +-- Description: syncronous 1-port ram with tech selection +------------------------------------------------------------------------------ + +library ieee; +use ieee.std_logic_1164.all; +use work.gencomp.all; +use work.allmem.all; + +entity syncram is + generic (tech : integer := 0; abits : integer := 6; dbits : integer := 8; + testen : integer := 0); + port ( + clk : in std_ulogic; + address : in std_logic_vector((abits -1) downto 0); + datain : in std_logic_vector((dbits -1) downto 0); + dataout : out std_logic_vector((dbits -1) downto 0); + enable : in std_ulogic; + write : in std_ulogic; + testin : in std_logic_vector(3 downto 0) := "0000"); +end; + +architecture rtl of syncram is + constant nctrl : integer := abits + 4; + signal rena, wena : std_logic; + signal dataoutx, databp, testdata : std_logic_vector((dbits -1) downto 0); + constant SCANTESTBP : boolean := (testen = 1) and (tech /= 0); +begin + + + -- RAM bypass for scan + scanbp : if SCANTESTBP generate + comb : process (address, datain, enable, write, testin) + variable tmp : std_logic_vector((dbits -1) downto 0); + variable ctrlsigs : std_logic_vector((nctrl -1) downto 0); + begin + ctrlsigs := testin(1 downto 0) & write & enable & address; + tmp := datain; + for i in 0 to nctrl-1 loop + tmp(i mod dbits) := tmp(i mod dbits) xor ctrlsigs(i); + end loop; + testdata <= tmp; + end process; + + reg : process (clk) + begin + if rising_edge(clk) then + databp <= testdata; + end if; + end process; + dmuxout : for i in 0 to dbits-1 generate + x0: grmux2 generic map (tech) + port map (dataoutx(i), databp(i), testin(3), dataout(i)); + end generate; + end generate; + + noscanbp : if not SCANTESTBP generate dataout <= dataoutx; end generate; + + inf : if tech = inferred generate + x0 : generic_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, write); + end generate; + + xcv : if (tech = virtex) generate + x0 : virtex_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + xc2v : if (is_unisim(tech) = 1) and (tech /= virtex) generate + x0 : unisim_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + vir : if tech = memvirage generate + x0 : virage_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + atrh : if tech = atc18rha generate + x0 : atc18rha_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write, testin); + end generate; + + axc : if (tech = axcel) or (tech = axdsp) generate + x0 : axcel_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + proa : if tech = proasic generate + x0 : proasic_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + umc18 : if tech = umc generate + x0 : umc_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + rhu : if tech = rhumc generate + x0 : rhumc_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + proa3 : if tech = apa3 generate + x0 : proasic3_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + fus : if tech = actfus generate + x0 : fusion_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + ihp : if tech = ihp25 generate + x0 : ihp25_syncram generic map(abits, dbits) + port map(clk, address, datain, dataoutx, enable, write); + end generate; + + ihprh : if tech = ihp25rh generate + x0 : ihp25rh_syncram generic map(abits, dbits) + port map(clk, address, datain, dataoutx, enable, write); + end generate; + + alt : if (tech = altera) or (tech = stratix1) or (tech = stratix2) or + (tech = stratix3) or (tech = cyclone3) generate + x0 : altera_syncram generic map(abits, dbits) + port map(clk, address, datain, dataoutx, enable, write); + end generate; + + rht : if tech = rhlib18t generate + x0 : rh_lib18t_syncram generic map(abits, dbits) + port map(clk, address, datain, dataoutx, enable, write, testin(1 downto 0)); + end generate; + + lat : if tech = lattice generate + x0 : ec_syncram generic map(abits, dbits) + port map(clk, address, datain, dataoutx, enable, write); + end generate; + + ut025 : if tech = ut25 generate + x0 : ut025crh_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + pere : if tech = peregrine generate + x0 : peregrine_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + arti : if tech = memartisan generate + x0 : artisan_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + cust1 : if tech = custom1 generate + x0 : custom1_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + ecl : if tech = eclipse generate + rena <= enable and not write; + wena <= enable and write; + x0 : eclipse_syncram_2p generic map(abits, dbits) + port map(clk, rena, address, dataoutx, clk, address, + datain, wena); + end generate; + + virage90 : if tech = memvirage90 generate + x0 : virage90_syncram generic map(abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + nex : if tech = easic90 generate + x0 : nextreme_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + + smic : if tech = smic013 generate + x0 : smic13_syncram generic map (abits, dbits) + port map (clk, address, datain, dataoutx, enable, write); + end generate; + +-- pragma translate_off + noram : if has_sram(tech) = 0 generate + x : process + begin + assert false report "synram: technology " & tech_table(tech) & + " not supported" + severity failure; + wait; + end process; + end generate; +-- pragma translate_on +end; + |