diff --git a/constraint/fp/user.pdc b/constraint/fp/user.pdc new file mode 100644 index 0000000000000000000000000000000000000000..750baa9b62aed01d8f24199572ca6b7158e858ee --- /dev/null +++ b/constraint/fp/user.pdc @@ -0,0 +1,36 @@ +# Microsemi Physical design constraints file + +# Version: v11.8 11.8.0.26 + +# Design Name: hydra + +# Input Netlist Format: EDIF + +# Family: SmartFusion2 , Die: M2S090 , Package: 484 FBGA , Speed grade: STD + +# Date generated: Tue Dec 01 16:43:52 2020 + + +# +# Local clock constraints +# + + +# +# Region constraints +# + +define_region -name UserRegion1 -type inclusive -color 2147442270 0 174 1019 260 +define_region -name UserRegion3 -type inclusive -color 2147442270 0 3 1019 92 +define_region -name UserRegion2 -type inclusive -color 2147442270 0 93 1019 173 +assign_region UserRegion1 soc/gen_cores.1.supervisor +assign_region UserRegion1 soc/gen_cores.1.urv_core +assign_region UserRegion3 soc/gen_cores.3.supervisor +assign_region UserRegion3 soc/gen_cores.3.urv_core +assign_region UserRegion2 soc/gen_cores.2.supervisor +assign_region UserRegion2 soc/gen_cores.2.urv_core + +# +# Core cell constraints +# + diff --git a/constraint/io/m2s050_som.io.pdc b/constraint/io/m2s050_som.io.pdc new file mode 100644 index 0000000000000000000000000000000000000000..346813f1e145d8bf92e04e44f824e584b898f484 --- /dev/null +++ b/constraint/io/m2s050_som.io.pdc @@ -0,0 +1,172 @@ +# Microsemi I/O Physical Design Constraints file +# Auto Generated User I/O Constraints file + +# Version: v11.8 11.8.0.26 +# Family: SmartFusion2 , Die: M2S090T , Package: 484 FBGA +# Date generated: Sun Jun 28 19:42:46 2020 + + +# +# User Locked I/O Bank Settings +# + + + +# +# Unlocked I/O Bank Settings +# The I/O Bank Settings can be locked by directly editing this file +# or by making changes in the I/O Attribute Editor +# + + +# +# User Locked I/O settings +# + +set_io CLK_I \ + -pinname H20 \ + -fixed yes \ + -DIRECTION INPUT + + +set_io GPIO_LED1 \ + -pinname AB18 \ + -fixed yes \ + -iostd LVCMOS25 \ + -DIRECTION OUTPUT + + +set_io GPIO_LED2 \ + -pinname P1 \ + -fixed yes \ + -iostd LVCMOS25 \ + -DIRECTION OUTPUT + + +set_io ETH_MDC_O \ + -pinname J4 \ + -fixed yes \ + -DIRECTION OUTPUT + + +set_io ETH_MDIO \ + -pinname J3 \ + -fixed yes \ + -DIRECTION INOUT + + +set_io {ETH_RXD_I[0]} \ + -pinname J1 \ + -fixed yes \ + -DIRECTION INPUT + + +set_io {ETH_RXD_I[1]} \ + -pinname H4 \ + -fixed yes \ + -DIRECTION INPUT + + +set_io {ETH_RXD_I[2]} \ + -pinname H5 \ + -fixed yes \ + -DIRECTION INPUT + + +set_io {ETH_RXD_I[3]} \ + -pinname G5 \ + -fixed yes \ + -DIRECTION INPUT + + +set_io ETH_RX_CLK_I \ + -pinname G1 \ + -fixed yes \ + -DIRECTION INPUT + + +set_io ETH_RX_DV_I \ + -pinname H1 \ + -fixed yes \ + -DIRECTION INPUT + + +set_io {ETH_TXD_O[0]} \ + -pinname F3 \ + -fixed yes \ + -DIRECTION OUTPUT + + +set_io {ETH_TXD_O[1]} \ + -pinname E1 \ + -fixed yes \ + -DIRECTION OUTPUT + + +set_io {ETH_TXD_O[2]} \ + -pinname D1 \ + -fixed yes \ + -DIRECTION OUTPUT + + +set_io {ETH_TXD_O[3]} \ + -pinname D2 \ + -fixed yes \ + -DIRECTION OUTPUT + + +set_io ETH_TX_CLK_I \ + -pinname E2 \ + -fixed yes \ + -DIRECTION INPUT + + +set_io ETH_TX_EN_O \ + -pinname F4 \ + -fixed yes \ + -DIRECTION OUTPUT +# +# +#set_io TEST_O \ + #-pinname B2 \ + #-fixed yes \ + #-DIRECTION OUTPUT + +# +#set_io eth_rst_o \ + #-pinname G6 \ + #-fixed yes \ + #-DIRECTION OUTPUT + + +set_io RST_I \ + -pinname U19 \ + -fixed yes \ + -RES_PULL Up \ + -DIRECTION INPUT + +# +#set_io rst_o \ + #-pinname K16 \ + #-fixed yes \ + #-DIRECTION OUTPUT +# +# +set_io uart_tx_o \ + -pinname E5 \ + -fixed yes \ + -DIRECTION OUTPUT + + + +# +# Dedicated Peripheral I/O Settings +# + + +# +# Unlocked I/O settings +# The I/Os in this section are unplaced or placed but are not locked +# the other listed attributes have been applied +# + diff --git a/constraint/timing.sdc b/constraint/timing.sdc new file mode 100644 index 0000000000000000000000000000000000000000..cb867e892613679c4d37f6ca410e8a66ebef3d6d --- /dev/null +++ b/constraint/timing.sdc @@ -0,0 +1,74 @@ +# Written by Synplify Pro version map201609actrcp1, Build 005R. Synopsys Run ID: sid1548081316 +# Top Level Design Parameters + +# Clocks +create_clock -period 20.000 -name {hydra|CLK_I} [get_ports {CLK_I}] +create_clock -period 40.000 -name {hydra|ETH_TX_CLK} [get_ports {ETH_TX_CLK_I}] +create_clock -period 40.000 -name {hydra|ETH_RX_CLK} [get_ports {ETH_RX_CLK_I}] + +# Virtual Clocks + +# Generated Clocks + +# Paths Between Clocks + +# Multicycle Constraints + +# Point-to-point Delay Constraints + +# False Path Constraints + +# Output Load Constraints + +# Driving Cell Constraints + +# Input Delay Constraints +set_input_delay -clock {hydra|ETH_RX_CLK} -min 9 [get_ports {ETH_RXD_I[*]}] +set_input_delay -clock {hydra|ETH_RX_CLK} -min 9 [get_ports {ETH_RX_DV_I}] +#set_input_delay -clock {hydra|ETH_RX_CLK} -min 9 [get_ports {ETH_RX_ER}] +set_input_delay -clock {hydra|ETH_RX_CLK} -max 30 [get_ports {ETH_RXD_I[*]}] +set_input_delay -clock {hydra|ETH_RX_CLK} -max 30 [get_ports {ETH_RX_DV_I}] +#set_input_delay -clock {hydra|ETH_RX_CLK} -max 30 [get_ports {ETH_RX_ER}] + +# Output Delay Constraints + +set_output_delay -clock {hydra|ETH_TX_CLK} -max 12 [get_ports {ETH_TXD_O[*]}] +set_output_delay -clock {hydra|ETH_TX_CLK} -max 12 [get_ports {ETH_TX_EN_O}] +set_output_delay -clock {hydra|ETH_TX_CLK} -min -1 [get_ports {ETH_TXD_O[*]}] +set_output_delay -clock {hydra|ETH_TX_CLK} -min -1 [get_ports {ETH_TX_EN_O}] + + + +# Wire Loads + +# Other Constraints + +# syn_hier Attributes + +# set_case Attributes + +# Clock Delay Constraints +set Inferred_clkgroup_0 [list hydra|CLK_I] +set Inferred_clkgroup_2 [list hydra|ETH_RX_CLK] +set Inferred_clkgroup_1 [list hydra|ETH_TX_CLK] + +set_clock_groups -asynchronous -group $Inferred_clkgroup_0 +set_clock_groups -asynchronous -group $Inferred_clkgroup_2 +set_clock_groups -asynchronous -group $Inferred_clkgroup_1 + + + +# syn_mode Attributes + +# Cells + +# Port DRC Rules + +# Input Transition Constraints + +# Unused constraints (intentionally commented out) + +# Non-forward-annotatable constraints (intentionally commented out) + +# Block Path constraints + diff --git a/hdl/axis_assert.vhd b/hdl/axis_assert.vhd new file mode 100644 index 0000000000000000000000000000000000000000..6fc13e1010a672276199f94d0d96fc097dc7d5e0 --- /dev/null +++ b/hdl/axis_assert.vhd @@ -0,0 +1,136 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.std_logic_textio.all; +use std.textio.all; + + + +entity axis_assert is + + generic ( + width : integer := 64; + axis_dbguser : boolean := true; + axis_dbglast : boolean := true; + tcq : integer := 5000 ); + port ( + clk : in std_logic; + reset : in std_logic; + + s_axis_data : in std_logic_vector(width-1 downto 0); + s_axis_valid : in std_logic; + s_axis_user : in std_logic; + s_axis_last : in std_logic; + ss_axis_ready : in std_logic; + + m_axis_ready : in std_logic ); + +end axis_assert; + + +architecture rtl of axis_assert is + + signal s_axis_data_r : std_logic_vector(width-1 downto 0); + signal s_axis_valid_r : std_logic; + signal s_axis_user_r : std_logic; + signal s_axis_last_r : std_logic; + signal ss_axis_ready_r : std_logic; + signal axis_user_next : std_logic; + signal axis_user_next_r : std_logic := '0'; + + + function or_reduce (x : std_logic_vector) return std_logic is + variable result : std_logic := '0'; + begin + + for i in x'range loop + result := result or x(i); + end loop; + return result; + end or_reduce; + +begin + --synthesis translate_off + + axis_user_next <= '1' when (s_axis_valid and s_axis_last and ss_axis_ready) = '1' else + '0' when (s_axis_valid and s_axis_user and ss_axis_ready) = '1' else axis_user_next_r; + process (clk) is + begin + if rising_edge(clk) then + if (reset = '1') then + s_axis_data_r <= s_axis_data after (tcq) * 1 ps; + s_axis_valid_r <= '0' after (tcq) * 1 ps; + s_axis_user_r <= '0' after (tcq) * 1 ps; + s_axis_last_r <= '0' after (tcq) * 1 ps; + ss_axis_ready_r <= '0' after (tcq) * 1 ps; + axis_user_next_r <= '0' after (tcq) * 1 ps; + else + s_axis_data_r <= s_axis_data after (tcq) * 1 ps; + s_axis_valid_r <= s_axis_valid after (tcq) * 1 ps; + s_axis_user_r <= s_axis_user after (tcq) * 1 ps; + s_axis_last_r <= s_axis_last after (tcq) * 1 ps; + ss_axis_ready_r <= ss_axis_ready after (tcq) * 1 ps; + axis_user_next_r <= axis_user_next after (tcq) * 1 ps; + end if; + end if; + end process; + + -- asserts + process (clk) + begin + if falling_edge(clk) then + if (reset = '0') then + if (s_axis_valid and ss_axis_ready and axis_user_next_r) = '1' then + if (s_axis_user /= '1' and axis_dbguser = true) then + -- report "WARNING: Custom axis scheme - s_axis_user expected. Probably illegal." severity failure; + end if; + end if; + + if s_axis_valid /= '0' and s_axis_valid /= '1' then + report "WARNING: s_axis_valid illegal(x)." severity failure; + end if; + + if m_axis_ready /= '0' and m_axis_ready /= '1' then + report "WARNING: m_axis_ready illegal(x)." severity failure; + end if; + + if (s_axis_valid_r and (not s_axis_valid) and (not ss_axis_ready_r)) = '1' then + report "ERROR: s_axis_valid deasserted illegally." severity failure; + end if; + + if (s_axis_valid = '1') then + if (s_axis_last /= '0' and s_axis_last /= '1' and axis_dbglast = true) then + report "WARNING: s_axis_last illegal(x)." severity failure; + end if; + + if (s_axis_user /= '0' and s_axis_user /= '1' and axis_dbguser = true) then + report "WARNING: s_axis_user _probably_ illegal(x)." severity failure; + end if; + + if (or_reduce(s_axis_data) /= '0' and or_reduce(s_axis_data) /= '1') then + report "WARNING: s_axis_data _probably_ illegal(x)." severity failure; + end if; + end if; + + if (s_axis_valid_r and s_axis_valid and (not ss_axis_ready_r)) = '1' then + if (s_axis_data /= s_axis_data_r) then + + + + report "ERROR: s_axis_data changed illegally." severity failure; + end if; + if (s_axis_last /= s_axis_last_r and axis_dbglast = true) then + report "ERROR: s_axis_last changed illegally." severity failure; + end if; + if (s_axis_user /= s_axis_user_r and axis_dbguser = true) then + report "CRITICAL WARNING: Custom axis scheme - s_axis_user changed illegally." severity failure; + end if; + end if; + end if; + end if; + end process; + + + --synthesis translate_on +end architecture; + diff --git a/hdl/axis_fifo_cdc.vhd b/hdl/axis_fifo_cdc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..70232dce92ca57678ad76eb1eb019ecfe7673aa6 --- /dev/null +++ b/hdl/axis_fifo_cdc.vhd @@ -0,0 +1,248 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +entity axis_fifo_cdc is + + generic ( + dwidth : integer := 128; + uwidth : integer := 1; + log2depth : integer := 9; + tcq : integer := 1 ); + port ( + s_clk : in std_logic; + s_reset : in std_logic; + + m_clk : in std_logic; + m_reset : in std_logic; + + s_axis_data : in std_logic_vector(dwidth-1 downto 0); + s_axis_valid : in std_logic; + s_axis_user : in std_logic_vector(uwidth-1 downto 0); + s_axis_last : in std_logic; + s_axis_ready : out std_logic; + s_axis_empty : out std_logic; + + m_axis_empty : out std_logic; + m_axis_data : out std_logic_vector(dwidth-1 downto 0); + m_axis_valid : out std_logic; + m_axis_user : out std_logic_vector(uwidth-1 downto 0); + m_axis_last : out std_logic; + m_axis_ready : in std_logic ); + + attribute keep_hierarchy : STRING; + attribute keep_hierarchy of axis_fifo_cdc : entity is "yes"; + +end axis_fifo_cdc; + +architecture rtl of axis_fifo_cdc is + + function bin2gray( binslv : std_logic_vector ) return std_logic_vector is + variable grayslv : std_logic_vector(binslv'range); + begin + for i in binslv'range loop + if i = binslv'left then + grayslv(i) := binslv(i); + else + grayslv(i) := binslv(i) xor binslv(i+1); + end if; + end loop; + return grayslv; + end function bin2gray; + + function gray2bin( grayslv : std_logic_vector ) return std_logic_vector is + variable binslv : std_logic_vector(grayslv'range); + begin + for i in grayslv'range loop + if i = grayslv'left then + binslv(i) := grayslv(i); + else + binslv(i) := grayslv(i) xor binslv(i+1); + end if; + end loop; + return binslv; + end; + + + function f_or (x : std_logic_vector) return std_logic is + variable result : std_logic := '0'; + begin + + for i in x'range loop + result := result or x(i); + end loop; + return result; + end f_or; + + signal maxspace : unsigned(log2depth-1 downto 0) := (others => '1'); + + signal fifo_wren : std_logic; + signal fifo_wraddr : std_logic_vector(log2depth downto 0); + signal fifo_wraddr_r : std_logic_vector(log2depth downto 0); + signal fifo_rdaddr : std_logic_vector(log2depth downto 0); + signal fifo_rdaddr_r : std_logic_vector(log2depth downto 0); + signal fifo_rdaddrp1 : std_logic_vector(log2depth downto 0); + signal fifo_rdaddrp1_r : std_logic_vector(log2depth downto 0); + signal fifo_wrdata : std_logic_vector(dwidth+uwidth+1-1 downto 0); + signal fifo_rddata : std_logic_vector(dwidth+uwidth+1-1 downto 0); + signal fifo_rddata_r : std_logic_vector(dwidth+uwidth+1-1 downto 0); + + signal fifo_wraddr_gray : std_logic_vector(log2depth downto 0); + signal fifo_wraddr_gray_r : std_logic_vector(log2depth downto 0); + signal fifo_wraddr_gray_cdc_r : std_logic_vector(log2depth downto 0); + signal fifo_wraddr_gray_cdc_h : std_logic_vector(log2depth downto 0); + signal fifo_wraddr_cdc : std_logic_vector(log2depth downto 0); + signal fifo_wraddr_cdc_r : std_logic_vector(log2depth downto 0); + + signal fifo_rdaddr_gray : std_logic_vector(log2depth downto 0); + signal fifo_rdaddr_gray_r : std_logic_vector(log2depth downto 0); + signal fifo_rdaddr_gray_cdc_r : std_logic_vector(log2depth downto 0); + signal fifo_rdaddr_gray_cdc_h : std_logic_vector(log2depth downto 0); + signal fifo_rdaddr_cdc : std_logic_vector(log2depth downto 0); + signal fifo_rdaddr_cdc_r : std_logic_vector(log2depth downto 0); + attribute async_reg : string; + attribute async_reg of fifo_wraddr_gray_cdc_r : signal is "true"; + attribute async_reg of fifo_wraddr_gray_cdc_h : signal is "true"; + attribute async_reg of fifo_rdaddr_gray_cdc_r : signal is "true"; + attribute async_reg of fifo_rdaddr_gray_cdc_h : signal is "true"; + + signal fifo_rdy : std_logic; + signal fifo_read : std_logic; + signal fifo_read_r : std_logic; + signal fifo_read_h : std_logic; + signal fifo_ready : std_logic; + signal fifo_ready_r : std_logic; + + signal fifo_space : unsigned(log2depth-1 downto 0); + signal fifo_space_r, fifo_space_m : unsigned(log2depth-1 downto 0); + signal fifo_dvalid : std_logic; + signal fifo_dvalid_r : std_logic; + signal fifo_restrobe : std_logic; + signal fifo_restrobe_r : std_logic; + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + +begin + + fifo_wren <= s_axis_valid and fifo_ready_r; + fifo_wraddr <= std_logic_vector((unsigned(fifo_wraddr_r) + 1)) when fifo_wren = '1' else fifo_wraddr_r; + fifo_wrdata <= (s_axis_last & s_axis_user & s_axis_data); + fifo_wraddr_gray <= bin2gray(fifo_wraddr); + fifo_rdaddr_cdc <= gray2bin(fifo_rdaddr_gray_cdc_h); + fifo_space <= maxspace + unsigned(fifo_rdaddr_cdc_r(log2depth-1 downto 0)) - unsigned(fifo_wraddr(log2depth-1 downto 0)); + fifo_ready <= '1' when f_or(std_logic_vector(fifo_space)) = '1' else '0'; + fifo_space_m <= maxspace + unsigned(fifo_rdaddr(log2depth-1 downto 0)) - unsigned(fifo_wraddr_cdc_r(log2depth-1 downto 0)); + mem_i : entity work.sdpram_cdc_r + generic map ( + width => dwidth + uwidth + 1, + log2depth => log2depth, + tcq => tcq ) + port map ( + wrclk => s_clk, + rdclk => m_clk, + wren => fifo_wren, + wraddr => fifo_wraddr_r(log2depth-1 downto 0), + rdaddr => fifo_rdaddr(log2depth-1 downto 0), + wrdata => fifo_wrdata, + rddata => fifo_rddata ); + + fifo_wraddr_cdc <= gray2bin(fifo_wraddr_gray_cdc_h); + fifo_rdy <= '1' when fifo_wraddr_cdc_r /= fifo_rdaddrp1_r else '0'; + fifo_read <= fifo_rdy and ((not (fifo_read_r or fifo_dvalid or fifo_restrobe_r)) or + ( fifo_read_r xor fifo_dvalid xor fifo_restrobe_r) or + ((not (fifo_read_r and fifo_dvalid and fifo_restrobe_r)) and m_axis_ready)); + fifo_rdaddr <= std_logic_vector(unsigned(fifo_rdaddr_r) + 1) when fifo_read = '1' else fifo_rdaddr_r; + fifo_rdaddrp1 <= std_logic_vector(unsigned(fifo_rdaddrp1_r) + 1) when fifo_read = '1' else fifo_rdaddrp1_r; + fifo_rdaddr_gray <= bin2gray(fifo_rdaddr); + + fifo_dvalid <= '1' when (fifo_read_h or fifo_dvalid_r) = '1' else '0'; + fifo_restrobe <= '1' when ((fifo_dvalid and (not m_axis_ready)) or (fifo_restrobe_r and (not m_axis_ready))) = '1' else '0'; + + + process (s_clk) is + begin + if rising_edge(s_clk) then + if s_reset = '1' then + fifo_ready_r <= '0' after (tcq) * 1 ps; + fifo_wraddr_r <= (others => '0') after (tcq) * 1 ps; + fifo_wraddr_gray_r <= (others => '0') after (tcq) * 1 ps; + fifo_rdaddr_gray_cdc_r(log2depth-2 downto 0) <= (others => '0') after (tcq) * 1 ps; + fifo_rdaddr_gray_cdc_r(log2depth-1) <= ('1') after (tcq) * 1 ps; + fifo_rdaddr_gray_cdc_h(log2depth-2 downto 0) <= (others => '0') after (tcq) * 1 ps; + fifo_rdaddr_gray_cdc_h(log2depth-1) <= ('1') after (tcq) * 1 ps; + fifo_rdaddr_cdc_r <= (others => '1') after (tcq) * 1 ps; + else + fifo_ready_r <= fifo_ready after (tcq) * 1 ps; + fifo_wraddr_r <= fifo_wraddr after (tcq) * 1 ps; + fifo_wraddr_gray_r <= fifo_wraddr_gray after (tcq) * 1 ps; + fifo_rdaddr_gray_cdc_r <= fifo_rdaddr_gray_r after (tcq) * 1 ps; + fifo_rdaddr_gray_cdc_h <= fifo_rdaddr_gray_cdc_r after (tcq) * 1 ps; + fifo_rdaddr_cdc_r <= fifo_rdaddr_cdc after (tcq) * 1 ps; + end if; + end if; + end process; + + + process (m_clk) is + begin + if rising_edge(m_clk) then + if m_reset = '1' then + fifo_wraddr_gray_cdc_r <= (others => '0') after (tcq) * 1 ps; + fifo_wraddr_gray_cdc_h <= (others => '0') after (tcq) * 1 ps; + fifo_wraddr_cdc_r <= (others => '0') after (tcq) * 1 ps; + fifo_rdaddr_r <= (others => '1') after (tcq) * 1 ps; + fifo_rdaddr_gray_r(log2depth-2 downto 0) <= (others => '0') after (tcq) * 1 ps; + fifo_rdaddr_gray_r(log2depth-1) <= ('1') after (tcq) * 1 ps; + fifo_rdaddrp1_r <= (others => '0') after (tcq) * 1 ps; + fifo_dvalid_r <= '0' after (tcq) * 1 ps; + fifo_restrobe_r <= '0' after (tcq) * 1 ps; + fifo_read_r <= '0' after (tcq) * 1 ps; + fifo_read_h <= '0' after (tcq) * 1 ps; + m_axis_empty <= '1'; + else + fifo_wraddr_gray_cdc_r <= fifo_wraddr_gray_r after (tcq) * 1 ps; + fifo_wraddr_gray_cdc_h <= fifo_wraddr_gray_cdc_r after (tcq) * 1 ps; + fifo_wraddr_cdc_r <= fifo_wraddr_cdc after (tcq) * 1 ps; + fifo_rdaddr_r <= fifo_rdaddr after (tcq) * 1 ps; + fifo_rdaddr_gray_r <= fifo_rdaddr_gray after (tcq) * 1 ps; + fifo_rdaddrp1_r <= fifo_rdaddrp1 after (tcq) * 1 ps; + fifo_restrobe_r <= fifo_restrobe after (tcq) * 1 ps; + fifo_read_r <= fifo_read after (tcq) * 1 ps; + fifo_read_h <= fifo_read_r after (tcq) * 1 ps; + + if (fifo_restrobe_r and ((not m_axis_ready) or fifo_dvalid)) = '1' then + fifo_dvalid_r <= fifo_dvalid after (tcq) * 1 ps; + else + fifo_dvalid_r <= '0' after (tcq) * 1 ps; + end if; + + if (fifo_restrobe and (not fifo_restrobe_r)) = '1' then + fifo_rddata_r <= fifo_rddata after (tcq) * 1 ps; + end if; + if (m_axis_ready = '1' and fifo_read = '0') then + + m_axis_empty <= '1'; + elsif ( (m_axis_ready = '1' and fifo_read = '1') or fifo_read = '1') then + m_axis_empty <= '0'; + end if; + + + end if; + end if; + end process; + + -- outputs + s_axis_ready <= fifo_ready_r; + s_axis_empty <= '1' when fifo_space = maxspace-1 else '0'; + m_axis_valid <= fifo_dvalid or fifo_restrobe_r; + + m_axis_data <= fifo_rddata_r(dwidth-1 downto 0) when fifo_restrobe_r = '1' else fifo_rddata(dwidth-1 downto 0); + m_axis_user <= fifo_rddata_r(dwidth+uwidth-1 downto dwidth) when fifo_restrobe_r = '1' else fifo_rddata(dwidth+uwidth-1 downto dwidth); + m_axis_last <= fifo_rddata_r(dwidth+uwidth) when fifo_restrobe_r = '1' else fifo_rddata(dwidth+uwidth); + + +end architecture; + + diff --git a/hdl/clock_buffer.vhd b/hdl/clock_buffer.vhd new file mode 100644 index 0000000000000000000000000000000000000000..7b8d59b87f54cb99f0e2f7b84b47fa3b6d9276c6 --- /dev/null +++ b/hdl/clock_buffer.vhd @@ -0,0 +1,46 @@ + +library IEEE; + +use IEEE.std_logic_1164.all; +library smartfusion2; +use smartfusion2.all; + +entity clock_buffer is +port ( + clk_i : in std_logic; + clk_sys_o : out std_logic; + clk_ram_o : out std_logic_vector (39 downto 0) +); +end clock_buffer; +architecture architecture_clk_buffer of clock_buffer is + component CLKINT_PRESERVE + port ( + A : in std_logic; + Y : out std_logic ); + end component; + component RCLKINT + port ( + A : in std_logic; + Y : out std_logic ); + end component; + + component BUFD + port ( + A : in std_logic; + Y : out std_logic ); + end component; +begin + + inst_clkint_sys : CLKINT_PRESERVE + port map ( + A => clk_i, + Y => clk_sys_o ); + + +gen_clks_iram : for i in 0 to 39 generate + inst_clkint : RCLKINT + port map ( + A => clk_SYS_O, + Y => clk_ram_o (i) ); +end generate; +end architecture_clk_buffer; diff --git a/hdl/dpram_generic.vhd b/hdl/dpram_generic.vhd new file mode 100644 index 0000000000000000000000000000000000000000..87fdd9a456e2b7cfff7eb5df2983317c2b191b0d --- /dev/null +++ b/hdl/dpram_generic.vhd @@ -0,0 +1,381 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +--library synplify; +--use synplify.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity dpram_generic is + + generic ( + g_addr_width : natural := 15; + g_data_width : natural := 42 + + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + clk_ram_i : in std_logic_vector (39 downto 0); + + da_i : in std_logic_vector(g_data_width-1 downto 0); + db_i : in std_logic_vector(g_data_width-1 downto 0); + aa_i : in std_logic_vector(g_addr_width-1 downto 0); + ab_i : in std_logic_vector(g_addr_width-1 downto 0); + wa_i : in std_logic_vector (3 downto 1); + wb_i : in std_logic; + ra_i : in std_logic; + rb_i : in std_logic; + + lock_a_req_i : in std_logic; + lock_b_req_i : in std_logic; + lock_a_grant_o : out std_logic; + lock_b_grant_o : out std_logic; + + qa_o : out std_logic_vector(g_data_width-1 downto 0); + qb_o : out std_logic_vector(g_data_width-1 downto 0); + valid_a_o : out std_logic; + valid_b_o : out std_logic + + + ); +end dpram_generic; + + +architecture rtl of dpram_generic is + component RAM1K18 +-- generic (MEMORYFILE:string := ""); + + port(A_DOUT : out std_logic_vector(17 downto 0); + B_DOUT : out std_logic_vector(17 downto 0); + BUSY : out std_logic; + A_CLK : in std_logic := 'U'; + A_DOUT_CLK : in std_logic := 'U'; + A_ARST_N : in std_logic := 'U'; + A_DOUT_EN : in std_logic := 'U'; + A_BLK : in std_logic_vector(2 downto 0) := (others => 'U'); + A_DOUT_ARST_N : in std_logic := 'U'; + A_DOUT_SRST_N : in std_logic := 'U'; + A_DIN : in std_logic_vector(17 downto 0) := (others => 'U'); + A_ADDR : in std_logic_vector(13 downto 0) := (others => 'U'); + A_WEN : in std_logic_vector(1 downto 0) := (others => 'U'); + B_CLK : in std_logic := 'U'; + B_DOUT_CLK : in std_logic := 'U'; + B_ARST_N : in std_logic := 'U'; + B_DOUT_EN : in std_logic := 'U'; + B_BLK : in std_logic_vector(2 downto 0) := (others => 'U'); + B_DOUT_ARST_N : in std_logic := 'U'; + B_DOUT_SRST_N : in std_logic := 'U'; + B_DIN : in std_logic_vector(17 downto 0) := (others => 'U'); + B_ADDR : in std_logic_vector(13 downto 0) := (others => 'U'); + B_WEN : in std_logic_vector(1 downto 0) := (others => 'U'); + A_EN : in std_logic := 'U'; + A_DOUT_LAT : in std_logic := 'U'; + A_WIDTH : in std_logic_vector(2 downto 0) := (others => 'U'); + A_WMODE : in std_logic := 'U'; + B_EN : in std_logic := 'U'; + B_DOUT_LAT : in std_logic := 'U'; + B_WIDTH : in std_logic_vector(2 downto 0) := (others => 'U'); + B_WMODE : in std_logic := 'U'; + SII_LOCK : in std_logic := 'U' + ); + end component; + + signal qa, qb, da, db : std_logic_vector (g_data_width downto 0); + + + signal addr_match : std_logic; + + signal lock_a_req, lock_b_req : std_logic; + signal lock_contention : std_logic; + + signal lock_a_grant, lock_b_grant, lock_a_grant_d, lock_b_grant_d : std_logic; + + signal wea, web : std_logic_vector (39 downto 0); + + + signal qa_discard_32k, qb_discard_32k : std_logic_vector (17 downto 2); + signal qa_discard_64k, qb_discard_64k : std_logic_vector (17 downto 1); + + signal rea, reb : std_logic; + signal wa_voted, wb_voted : std_logic; +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; +begin + + + + addr_match <= '1' when (aa_i (7 downto 2) = ab_i (7 downto 2)) else '0'; --to save LUTs, overhead + --is only 0.5% (random address) + da <= "0" & da_i; + db <= "0" & db_i; + qa_o <= qa (g_data_width-1 downto 0); + qb_o <= qb (g_data_width-1 downto 0); + + + wa_voted <= ( (wa_i(1) and wa_i(2)) or (wa_i(1) and wa_i(3)) or (wa_i(2) and wa_i(3))) ; + + process (lock_b_grant, lock_a_grant, addr_match, ra_i, rb_i, wa_voted, wb_i) + begin + + if (lock_b_grant = '1') then + valid_b_o <= '1'; + else + valid_b_o <= '0' when (((rb_i and wa_voted) or lock_a_grant) and addr_match) else '1'; + end if; + + if (lock_a_grant = '1') then + valid_a_o <= '1'; +else + valid_a_o <= '0' when (((ra_i and wb_i) or lock_b_grant) and addr_match) else '1'; +end if; +end process; + + +tmr_signals : for i in 0 to 39 generate + wea (i) <= ( (wa_i(1) and wa_i(2)) or (wa_i(1) and wa_i(3)) or (wa_i(2) and wa_i(3))) and valid_a_o; + -- "web" signal not TMRed (it requires a block TMR of the scrubber) + web (i) <= wb_i and valid_b_o; +end generate; + + + + + lock_a_grant_o <= lock_a_grant; + lock_b_grant_o <= lock_b_grant; + + lock_contention <= addr_match and lock_a_req_i and lock_b_req_i; + + + + lock_a_req <= lock_a_req_i; + lock_b_req <= lock_b_req_i; + +assert ( (lock_a_grant_o and lock_b_grant_o and addr_match) = '0') report "error grant" severity error; + + + process (clk_i, rst_i) + begin + if rising_edge (clk_i) then + if rst_i = '1' then + lock_a_grant_d <= '0'; + lock_b_grant_d <= '0'; + else + lock_a_grant_d <= lock_a_grant; + lock_b_grant_d <= lock_b_grant; + + end if; + end if; + end process; + + -- lock_a/b_req signal, after the write is done, will always be deasserted for at least one clock cycle + + process (lock_contention, lock_a_req, lock_b_req, lock_a_grant_d, lock_b_grant_d) + begin + + if (lock_contention = '0') then + lock_a_grant <= lock_a_req; + lock_b_grant <= lock_b_req; + else + if (lock_a_grant_d = '0' and lock_b_grant_d = '0') then + if (lock_b_req = '1' and lock_a_req = '0') then + lock_b_grant <= '1'; + lock_a_grant <= '0'; + elsif (lock_a_req = '1') then + lock_a_grant <= '1'; + lock_b_grant <= '0'; + else + lock_a_grant <= '0'; + lock_b_grant <= '0'; + end if; + else + lock_a_grant <= lock_a_grant_d; + lock_b_grant <= lock_b_grant_d; + end if; + end if; + + end process; + + + gen_32k_daec : if (g_addr_width = 15 and g_data_width = 42) generate + + gen_bram : for i in 1 to 5 generate + gen_byte : for k in 0 to 3 generate + sram_two_bit : RAM1K18 + + port map( + A_WIDTH => "001", + B_WIDTH => "001", + A_WMODE => '1', --write data appears on the corresponding read data port + B_WMODE => '1', --write data appears on the corresponding read data port + A_DOUT_LAT => '1', + B_DOUT_LAT => '1', + A_EN => '1', + B_EN => '1', + A_ARST_N => '1', + B_ARST_N => '1', + A_DOUT_EN => '1', + B_DOUT_EN => '1', + A_DOUT_SRST_N => '1', + B_DOUT_SRST_N => '1', + A_DOUT_ARST_N => '1', + B_DOUT_ARST_N => '1', + SII_LOCK => '1', + A_DOUT_CLK => '1', + B_DOUT_CLK => '1', + + A_CLK => clk_ram_i (8*(i-1)+k), + B_CLK => clk_ram_i (8*(i-1)+k), + + A_WEN (1) => '0', + A_WEN (0) => wea (8*(i-1)+2*k), + B_WEN (1) => '0', + B_WEN (0) => web (8*(i-1)+2*k), + + A_DIN (1 downto 0) => da(8*(i-1)+2*k+1 downto 8*(i-1)+2*k) , + A_DIN (17 downto 2) => (others => '0'), + B_DIN (1 downto 0) => db(8*(i-1)+2*k+1 downto 8*(i-1)+2*k), + B_DIN (17 downto 2) => (others => '0'), + + A_ADDR (0 downto 0) => "0", + A_ADDR (13 downto 1) => aa_i(14 downto 2), + B_ADDR (0 downto 0) => "0", + B_ADDR (13 downto 1) => ab_i(14 downto 2), + + + A_BLK => (others => '1'), + B_BLK => (others => '1'), + + + A_DOUT (17 downto 2) => qa_discard_32k (17 downto 2), + A_DOUT (1 downto 0) => qa(8*(i-1)+2*k+1 downto 8*(i-1)+2*k), + b_DOUT (17 downto 2) => qb_discard_32k (17 downto 2), + B_DOUT (1 downto 0) => qb(8*(i-1)+2*k+1 downto 8*(i-1)+2*k) + + ); + + end generate gen_byte; + + end generate gen_bram; + + sram_two_bit : RAM1K18 + + port map( + A_WIDTH => "001", + B_WIDTH => "001", + A_WMODE => '1', --write data appears on the corresponding read data port + B_WMODE => '1', --write data appears on the corresponding read data port + A_DOUT_LAT => '1', + B_DOUT_LAT => '1', + A_EN => '1', + B_EN => '1', + A_ARST_N => '1', + B_ARST_N => '1', + A_DOUT_EN => '1', + B_DOUT_EN => '1', + A_DOUT_SRST_N => '1', + B_DOUT_SRST_N => '1', + A_DOUT_ARST_N => '1', + B_DOUT_ARST_N => '1', + SII_LOCK => '1', + A_DOUT_CLK => '1', + B_DOUT_CLK => '1', + + A_CLK => clk_i, + B_CLK => clk_i, + + A_WEN (1) => '0', + A_WEN (0) => wea (39), + B_WEN (1) => '0', + B_WEN (0) => web (39), + + A_DIN (1 downto 0) => da(41 downto 40), + A_DIN (17 downto 2) => (others => '0'), + B_DIN (1 downto 0) => db(41 downto 40), + B_DIN (17 downto 2) => (others => '0'), + + A_ADDR (0 downto 0) => "0", + A_ADDR (13 downto 1) => aa_i(14 downto 2), + B_ADDR (0 downto 0) => "0", + B_ADDR (13 downto 1) => ab_i(14 downto 2), + + A_BLK => (others => '1'), + B_BLK => (others => '1'), + + A_DOUT (17 downto 2) => qa_discard_32k(17 downto 2), + A_DOUT (1 downto 0) => qa(41 downto 40), + b_DOUT (17 downto 2) => qb_discard_32k(17 downto 2), + B_DOUT (1 downto 0) => qb(41 downto 40) + + ); + + + end generate gen_32k_daec; + + gen_64k : if g_addr_width = 16 generate + + gen_bram : for i in 1 to 5 generate + + gen_byte : for k in 0 to 7 generate + + sram_bit : RAM1K18 + + port map( + A_WIDTH => "000", + B_WIDTH => "000", + A_WMODE => '1', --write data appears on the corresponding read data port + B_WMODE => '1', --write data appears on the corresponding read data port + A_DOUT_LAT => '1', + B_DOUT_LAT => '1', + A_EN => '1', + B_EN => '1', + A_ARST_N => '1', + B_ARST_N => '1', + A_DOUT_EN => '1', + B_DOUT_EN => '1', + A_DOUT_SRST_N => '1', + B_DOUT_SRST_N => '1', + A_DOUT_ARST_N => '1', + B_DOUT_ARST_N => '1', + SII_LOCK => '1', + A_DOUT_CLK => '1', + B_DOUT_CLK => '1', + + A_CLK => clk_ram_i (8*(i-1)+k), + B_CLK => clk_ram_i (8*(i-1)+k), + + A_WEN (1) => '0', + A_WEN (0) => wea (8*(i-1)+k), + B_WEN (1) => '0', + B_WEN (0) => web (8*(i-1)+k), + + A_DIN (0 downto 0) => da(8*(i-1)+k downto 8*(i-1)+k), + A_DIN (17 downto 1) => (others => '0'), + B_DIN (0 downto 0) => db(8*(i-1)+k downto 8*(i-1)+k), + B_DIN (17 downto 1) => (others => '0'), + + --A_ADDR (0 downto 0) => "0", + A_ADDR (13 downto 0) => aa_i(15 downto 2), + --B_ADDR (0 downto 0) => "0", + B_ADDR (13 downto 0) => ab_i(15 downto 2), + + + A_BLK => (others => '1'), + B_BLK => (others => '1'), + + A_DOUT (17 downto 1) => qa_discard_64k, + A_DOUT (0 downto 0) => qa(8*(i-1)+k downto 8*(i-1)+k), + b_DOUT (17 downto 1) => qb_discard_64k, + B_DOUT (0 downto 0) => qb(8*(i-1)+k downto 8*(i-1)+k) + + ); + end generate gen_byte; + + end generate gen_bram; + end generate gen_64k; + + + + end architecture; \ No newline at end of file diff --git a/hdl/eth_tx_buffers.vhd b/hdl/eth_tx_buffers.vhd new file mode 100644 index 0000000000000000000000000000000000000000..4b38984fc5e52ce65fbcbebec0bc738a1b3d603c --- /dev/null +++ b/hdl/eth_tx_buffers.vhd @@ -0,0 +1,42 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity eth_tx_buffers is + + + port ( + eth_tx_clk_i : in std_logic; + + txd_i : in std_logic_vector(3 downto 0); + txen_i : in std_logic; + txd_o : out std_logic_vector (3 downto 0); + txen_o : out std_logic +); +end entity; + +architecture rtl of eth_tx_buffers is +begin + +process (eth_tx_clk_i) +begin +if rising_edge(eth_tx_clk_i) then +txd_o <= txd_i; +txen_o <= txen_i; +end if; +end process; + +end architecture; + diff --git a/hdl/mg_sdpram_cdc.vhd b/hdl/mg_sdpram_cdc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a39bff16edf3d1a5c2695a2a68f972fe4bde6d46 --- /dev/null +++ b/hdl/mg_sdpram_cdc.vhd @@ -0,0 +1,56 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity mg_sdpram_cdc is + + generic ( + width : integer := 72; + log2depth : integer := 10; + tcq : integer := 5000 ); + port ( + wrclk : in std_logic; + rdclk : in std_logic; + + wren : in std_logic; + wraddr : in std_logic_vector(log2depth-1 downto 0); + rdaddr : in std_logic_vector(log2depth-1 downto 0); + + wrdata : in std_logic_vector(width-1 downto 0); + rddata : out std_logic_vector(width-1 downto 0) ); + +end mg_sdpram_cdc; + + +architecture rtl of mg_sdpram_cdc is + + type regfile_t is array (integer range <>) of std_logic_vector (width-1 downto 0); + signal regs : regfile_t (0 to ((2**log2depth)-1)); + + signal rddata_r : std_logic_vector(width-1 downto 0); + signal rddata_h : std_logic_vector(width-1 downto 0); + +begin + + process (wrclk) + begin + if (rising_edge(wrclk)) then + if (wren = '1') then + regs(to_integer(unsigned(wraddr))) <= wrdata after (tcq) * 1 ps; + end if; + end if; + end process; + + process (rdclk) + begin + if (rising_edge(rdclk)) then + rddata_r <= regs(to_integer(unsigned(rdaddr))) after (tcq) * 1 ps; + end if; + end process; + + -- outputs + rddata <= rddata_r; + +end architecture; + + diff --git a/hdl/ram_voter.vhd b/hdl/ram_voter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..84f1cb8ce2ddd2df2b08c407edc6009f02646b04 --- /dev/null +++ b/hdl/ram_voter.vhd @@ -0,0 +1,74 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; + +--library smartfusion2; +--use smartfusion2.all; + +package voter is + type t_voter_stdvector is array (1 to 3) of std_logic_vector; + type t_voter_stdlogic is array (1 to 3) of std_logic; +end package; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.voter.all; + +entity ram_voter is + generic ( + g_addr_width : natural := 15; + g_data_width : natural := 38 + + ); + port ( + da_vot_i : in t_voter_stdvector (open)(g_data_width-1 downto 0); + aa_vot_i : in t_voter_stdvector (open) (g_addr_width-1 downto 0); + wa_vot_i : in t_voter_stdlogic; + ra_vot_i : in t_voter_stdlogic; + + lock_a_req_vot_i : in t_voter_stdlogic; + + da_o : out std_logic_vector (g_data_width-1 downto 0); + aa_o : out std_logic_vector (g_addr_width-1 downto 0); + wa_o : out std_logic; + ra_o : out std_logic; + lock_a_req_o : out std_logic + + + ); + + +end ram_voter; + +architecture rtl of ram_voter is + + +begin + + da : for i in da_o'range generate + da_o(i) <= (da_vot_i(1)(i) and da_vot_i(2)(i)) or (da_vot_i(2)(i) and da_vot_i(3)(i)) or (da_vot_i(1)(i) and da_vot_i(3)(i)); + + end generate; + + aa : for i in aa_o'range generate + aa_o(i) <= (aa_vot_i(1)(i) and aa_vot_i(2)(i)) or (aa_vot_i(2)(i) and aa_vot_i(3)(i)) or (aa_vot_i(1)(i) and aa_vot_i(3)(i)); + + end generate; + + wa_o <= (wa_vot_i(1) and wa_vot_i(2)) or (wa_vot_i(2) and wa_vot_i(3)) or (wa_vot_i(1) and wa_vot_i(3)); + + ra_o <= (ra_vot_i(1) and ra_vot_i(2)) or (ra_vot_i(2) and ra_vot_i(3)) or (ra_vot_i(1) and ra_vot_i(3)); + + + lock_a_req_o <= (lock_a_req_vot_i(1) and lock_a_req_vot_i(2)) or (lock_a_req_vot_i(2) and lock_a_req_vot_i(3)) or (lock_a_req_vot_i(1) and lock_a_req_vot_i(3)); + + +end architecture; diff --git a/hdl/reset_gen.vhd b/hdl/reset_gen.vhd new file mode 100644 index 0000000000000000000000000000000000000000..cb4050ae8f767ad13f83270f07a812678d9f9131 --- /dev/null +++ b/hdl/reset_gen.vhd @@ -0,0 +1,88 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +--library smartfusion2; +--use smartfusion2.all; + + +entity reset_gen is + + port ( + clk_i : in std_logic; + rst_por_i : in std_logic; + rst_btn_i : in std_logic; + wd_i : in std_logic; + rst_soc_o : out std_logic; + rst_mss_o : out std_logic + + + ); +end entity reset_gen; + + +architecture rtl of reset_gen is + + +signal rst, rst_btn, rst_btn_d : std_logic; +signal rst_por, por_filter0, por_filter1 : std_logic; +-- if USB is used to power-up the board, additional delay is required (more than 1ms) +signal counter : unsigned (17 downto 0) ; + + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + +begin + + +process (clk_i) +begin +if rising_edge(clk_i) then + rst_btn_d <= rst_btn_i; + rst_btn <= rst_btn_d; +end if; +end process; + +process (rst_por_i, clk_i) +begin +if (rst_por_i = '1') then + por_filter0 <= '1'; + por_filter1 <= '1'; +elsif rising_edge (clk_i) then + por_filter0 <= '0'; + por_filter1 <= por_filter0; +end if; +end process; + +rst_por <= por_filter1; + +rst <= rst_por or rst_btn or (wd_i and not rst_soc_o); + +process (clk_i) +begin +if rst = '1' then +counter <= (others => '0'); +rst_soc_o <= '1'; +rst_mss_o <= '1'; +elsif rising_edge(clk_i) then +-- 1ms delay w.r.t. rst_mss_o +if (counter = (counter'range => '1')) then + rst_soc_o <= '0'; +else + counter <= counter+1; +end if; + +if (counter (2) = '1') then + rst_mss_o <= '0'; +end if; + +end if; + +end process; + + +end architecture; diff --git a/hdl/rst_filter.vhd b/hdl/rst_filter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..f14045bba47b4fe79e1571a9154185f89c58df1e --- /dev/null +++ b/hdl/rst_filter.vhd @@ -0,0 +1,53 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + + + +entity rst_filter is + + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + rst_o : out std_logic ); +end entity; + + architecture rtl of rst_filter is + signal rst_rising, rst_falling : std_logic; + + attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + + begin + + + process (clk_i) + begin + if rising_edge(clk_i) then + rst_rising <= rst_I; + end if; +end process; + + process (clk_i) + begin + if rising_edge(clk_i) then + rst_falling <= rst_rising; + end if; +end process; + +process (rst_rising, rst_falling) + begin + if (rst_rising = '1' and rst_falling = '1') then + rst_o <= '1'; + else + rst_o <= '0'; +end if; +end process; + + + + + end architecture; \ No newline at end of file diff --git a/hdl/sdram_cdc_r.vhd b/hdl/sdram_cdc_r.vhd new file mode 100644 index 0000000000000000000000000000000000000000..9000d72dac057efb4df5fb37ceea90f4dc14dbbb --- /dev/null +++ b/hdl/sdram_cdc_r.vhd @@ -0,0 +1,57 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity sdpram_cdc_r is + + generic ( + width : integer := 72; + log2depth : integer := 10; + tcq : integer := 1 ); + port ( + wrclk : in std_logic; + rdclk : in std_logic; + + wren : in std_logic; + wraddr : in std_logic_vector(log2depth-1 downto 0); + rdaddr : in std_logic_vector(log2depth-1 downto 0); + + wrdata : in std_logic_vector(width-1 downto 0); + rddata : out std_logic_vector(width-1 downto 0) ); + +end sdpram_cdc_r; + + +architecture rtl of sdpram_cdc_r is + + type regfile_t is array (integer range <>) of std_logic_vector (width-1 downto 0); + signal regs : regfile_t (0 to ((2**log2depth)-1)); + + signal rddata_r : std_logic_vector(width-1 downto 0); + signal rddata_h : std_logic_vector(width-1 downto 0); + +begin + + process (wrclk) + begin + if (rising_edge(wrclk)) then + if (wren = '1') then + regs(to_integer(unsigned(wraddr))) <= wrdata after (tcq) * 1 ps; + end if; + end if; + end process; + + process (rdclk) + begin + if (rising_edge(rdclk)) then + rddata_r <= regs(to_integer(unsigned(rdaddr))) after (tcq) * 1 ps; + rddata_h <= rddata_r after (tcq) * 1 ps; + end if; + end process; + + -- outputs + rddata <= rddata_h; + +end architecture; + + diff --git a/hdl/secded_ecc.vhd b/hdl/secded_ecc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..4650e2ce96ce8c5d7b0e22dd923e14788af1f687 --- /dev/null +++ b/hdl/secded_ecc.vhd @@ -0,0 +1,443 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +entity secded_ecc is + + + + generic ( + g_addr_width : natural := 16 + + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + -- to the processor/bus + d_i : in std_logic_vector(31 downto 0); + a_i : in std_logic_vector(g_addr_width-1 downto 0); + we_i : in std_logic; + bwe_i : in std_logic_vector (3 downto 0); + re_i : in std_logic; + + q_o : out std_logic_vector(31 downto 0); + done_r_o : out std_logic; + done_w_o : out std_logic; + + --to the BRAM + d_ram_i : in std_logic_vector (38 downto 0); + q_ram_o : out std_logic_vector (38 downto 0); + a_ram_o : out std_logic_vector (g_addr_width-1 downto 0); + we_ram_o : out std_logic; + re_ram_o : out std_logic; + valid_ram_i : in std_logic; + lock_req_o : out std_logic; + lock_grant_i : in std_logic; + + + + single_error_p_o : out std_logic; + double_error_p_o : out std_logic; + read_fault_p_o : out std_logic; + write_fault_p_o : out std_logic + ); + + +end secded_ecc; +architecture rtl of secded_ecc is + + + function f_xor (x : std_logic_vector) return std_logic is + variable result : std_logic := '0'; + begin + + for i in x'range loop + result := result xor x(i); + end loop; + return result; + end f_xor; + + function f_or (x : std_logic_vector) return std_logic is + variable result : std_logic := '0'; + begin + + for i in x'range loop + result := result or x(i); + end loop; + return result; + end f_or; + + function f_and (x : std_logic_vector) return std_logic is + variable result : std_logic := '1'; + begin + + for i in x'range loop + result := result and x(i); + end loop; + return result; + end f_and; + + constant syndrome_s1_mask : std_logic_vector (31 downto 0) := "11000001010010000100000011111111"; + constant syndrome_s2_mask : std_logic_vector (31 downto 0) := "00100001001001001111111110010000"; + constant syndrome_s3_mask : std_logic_vector (31 downto 0) := "01101100111111110000100000001000"; + constant syndrome_s4_mask : std_logic_vector (31 downto 0) := "11111111000000011010010001000100"; + constant syndrome_s5_mask : std_logic_vector (31 downto 0) := "00010110111100001001001010100110"; + constant syndrome_s6_mask : std_logic_vector (31 downto 0) := "00010000000111110111000101100001"; + constant syndrome_s7_mask : std_logic_vector (31 downto 0) := "10001010100000100000111100011011"; + + type array_syndrome is array (0 to 38) of std_logic_vector (6 downto 0); + constant syn_correction_mask : array_syndrome := ( + 0 => "1100001", + 1 => "1010001", + 2 => "0011001", + 3 => "1000101", + 4 => "1000011", + 5 => "0110001", + 6 => "0101001", + 7 => "0010011", + 8 => "1100010", + 9 => "1010010", + 10 => "1001010", + 11 => "1000110", + 12 => "0110010", + 13 => "0101010", + 14 => "0100011", + 15 => "0011010", + 16 => "0101100", + 17 => "1100100", + 18 => "0100110", + 19 => "0100101", + 20 => "0110100", + 21 => "0010110", + 22 => "0010101", + 23 => "1010100", + 24 => "0001011", + 25 => "1011000", + 26 => "0011100", + 27 => "1001100", + 28 => "0111000", + 29 => "0001110", + 30 => "0001101", + 31 => "1001001", + 32 => "0000001", + 33 => "0000010", + 34 => "0000100", + 35 => "0001000", + 36 => "0010000", + 37 => "0100000", + 38 => "1000000"); + + + + function f_calc_syndrome (data : std_logic_vector (38 downto 0)) return std_logic_vector is + variable result : std_logic_vector (6 downto 0); + begin + result (0) := f_xor (data(31 downto 0) and syndrome_s1_mask) xor data(32); + result (1) := f_xor (data(31 downto 0) and syndrome_s2_mask) xor data(33); + result (2) := f_xor (data(31 downto 0) and syndrome_s3_mask) xor data(34); + result (3) := f_xor (data(31 downto 0) and syndrome_s4_mask) xor data(35); + result (4) := f_xor (data(31 downto 0) and syndrome_s5_mask) xor data(36); + result (5) := f_xor (data(31 downto 0) and syndrome_s6_mask) xor data(37); + result (6) := f_xor (data(31 downto 0) and syndrome_s7_mask) xor data(38); + return result; + end f_calc_syndrome; + + + function f_ecc_word (data : std_logic_vector (31 downto 0)) return std_logic_vector is + variable result : std_logic_vector (38 downto 0); + begin + result (31 downto 0) := data; + result (38 downto 32) := f_calc_syndrome ("0000000" & data); + return result; + end f_ecc_word; + + + + function f_ecc_errors (syndrome : std_logic_vector (6 downto 0)) return std_logic is + begin + if Is_x (syndrome (0)) then + -- report "memory wrong" severity error; + return 'X'; + else + return f_or (syndrome); + end if; + end f_ecc_errors; + + function f_ecc_one_error (syndrome : std_logic_vector (6 downto 0)) return std_logic is + variable syndrome_bound_check : std_logic; + begin + if Is_x (syndrome (0)) then + return '0'; + else + return f_ecc_errors (syndrome) and f_xor (syndrome); + end if; + end f_ecc_one_error; + + function f_fix_error (syndrome : std_logic_vector (6 downto 0); data : std_logic_vector (38 downto 0)) return std_logic_vector is + variable result : std_logic_vector (38 downto 0) := (others => '1'); + variable mask : std_logic_vector (6 downto 0); + variable corrected_word : std_logic_vector (38 downto 0); + begin + for i in 0 to 38 loop + mask := syn_correction_mask(i); + for k in mask'range loop + if (mask (k) = '1') then + result(i) := result(i) and syndrome(k); + end if; + end loop; + end loop; + + + if (f_or (result(31 downto 0)) = '1') then + corrected_word := data (38 downto 32) & (result (31 downto 0) xor data(31 downto 0)); + elsif (f_or (result(38 downto 32)) = '1') then + corrected_word := result xor data; + else + corrected_word := "0000000" & x"00000000"; + end if; + + return corrected_word; + end f_fix_error; + + function f_mask_word (mask : std_logic_vector (3 downto 0); d1 : std_logic_vector (31 downto 0); d2 : std_logic_vector (31 downto 0)) return std_logic_vector is + variable masked_word : std_logic_vector (31 downto 0); + begin + for i in 1 to 4 loop + if (mask(i-1) = '0') then + masked_word (i*8-1 downto (i-1)*8) := d2(i*8-1 downto (i-1)*8); + else + masked_word (i*8-1 downto (i-1)*8) := d1(i*8-1 downto (i-1)*8); + end if; + end loop; + return masked_word; + end f_mask_word; + + type fsm_read_states is (normal_op, check_again, wait_lock, wait_correction); + type fsm_write_states is (normal_op, check_write); + type fsm_rw_states is (idle, wait_lock, wait_read, wait_write); + + signal fsm_read : fsm_read_states := normal_op; + signal fsm_write : fsm_write_states := normal_op; + signal fsm_rw : fsm_rw_states := idle; + + + signal ecc_errors, ecc_correctable_error : std_logic; + signal syndrome : std_logic_vector (6 downto 0); + + + signal re_d, re_fsm, we_fsm, re, we, valid_ram_d : std_logic; + signal done_r, done_w, fsm_done_r_p, fsm_done_rw_p : std_logic; + signal lock_req_r, lock_req_rw : std_logic; + signal req_correction, ack_correction : std_logic; + signal fsm_read_normal : std_logic; +signal d, d_rw : std_logic_vector (31 downto 0); + + signal q_ram : std_logic_vector (38 downto 0); +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; +begin + + + + + q_o <= d_ram_i (31 downto 0); + re_ram_o <= '1' when (fsm_read /= normal_op) else re; + + syndrome <= f_calc_syndrome (d_ram_i); + ecc_errors <= f_ecc_errors(syndrome); + ecc_correctable_error <= f_ecc_one_error (syndrome); + + fsm_read_normal <= '1' when fsm_read = normal_op else '0'; + done_r <= (re_d and valid_ram_d and fsm_read_normal and not ecc_errors) or fsm_done_r_p; + done_r_o <= done_r when (fsm_rw = idle) else '0'; + done_w_o <= '1' when (fsm_done_rw_p = '1' or (done_w = '1' and (fsm_rw = idle))) else '0'; + + +process (rst_i, a_i, q_ram) + begin + -- synthesis translate_off + + if rst_i = '1' then + a_ram_o <= (others => '0'); + q_ram_o <= (others => '0'); + elsE + -- synthesis translate_on + a_ram_o <= a_i; + q_ram_o <= q_ram; + -- synthesis translate_off +end if; + +-- synthesis translate_on + +end process; + + lock_req_o <= lock_req_r or lock_req_rw; + + + + we <= we_i when (bwe_i = "1111") else we_fsm; + re <= re_i or re_fsm; + d <= d_i when (fsm_rw = idle) else d_rw; + + -- this FSM is used for sub-word writing, which require a word read and a word write + -- the read and write is atomic, dual-port thread-safe + + process (clk_i) + begin + if rising_edge (clk_i) then + if rst_i = '1' then + fsm_rw <= idle; + lock_req_rw <= '0'; + re_fsm <= '0'; + we_fsm <= '0'; + fsm_done_rw_p <= '0'; + else + case (fsm_rw) is + when idle => + fsm_done_rw_p <= '0'; + if (we_i = '1' and bwe_i /= "1111") then + + lock_req_rw <= '1'; + fsm_rw <= wait_lock; + end if; + when wait_lock => + if (lock_grant_i = '1') then + re_fsm <= '1'; + fsm_rw <= wait_read; + end if; + when wait_read => + re_fsm <= '0'; + if (done_r = '1') then + d_rw <= f_mask_word (bwe_i, d_i, d_ram_i (31 downto 0)); + fsm_rw <= wait_write; + we_fsm <= '1'; + end if; + when wait_write => + we_fsm <= '0'; + if (done_w = '1') then + fsm_done_rw_p <= '1'; + lock_req_rw <= '0'; + fsm_rw <= idle; + end if; + when others => + fsm_rw <= idle; + + end case; + end if; + end if; + end process; + + + + process (clk_i) + begin + if rising_edge(clk_i) then + if rst_i = '1' then + fsm_read <= normal_op; + re_d <= '0'; + fsm_done_r_p <= '0'; + lock_req_r <= '0'; + req_correction <= '0'; + single_error_p_o <= '0'; + double_error_p_o <= '0'; + else + re_d <= re; + valid_ram_d <= valid_ram_i; + + case (fsm_read) is + when normal_op => + + fsm_done_r_p <= '0'; + single_error_p_o <= '0'; + double_error_p_o <= '0'; + if (re_d = '1' and done_r = '0' and valid_ram_d = '1' and ecc_errors = '1') then + fsm_read <= check_again; -- SET? + end if; + when check_again => + if (valid_ram_d = '1' and ecc_errors = '1') then + if (ecc_correctable_error = '0') then + double_error_p_o <= '1'; + fsm_done_r_p <= '1'; + fsm_read <= normal_op; + else + lock_req_r <= '1'; + fsm_read <= wait_lock; + end if; + elsif (valid_ram_d = '1' and ecc_errors = '0') then + fsm_read <= normal_op; + + end if; + when wait_lock => + if (lock_grant_i = '1') then + req_correction <= '1'; + fsm_read <= wait_correction; + end if; + when wait_correction => + --req_correction <= '0'; + if (ack_correction = '1') then + req_correction <= '0'; + fsm_read <= normal_op; + fsm_done_r_p <= '1'; + single_error_p_o <= '1'; + lock_req_r <= '0'; + end if; + + end case; + end if; + end if; + end process; + + + + + + process (clk_i) + begin + if rising_edge (clk_i) then + if rst_i = '1' then + fsm_write <= normal_op; + done_w <= '0'; + we_ram_o <= '0'; + write_fault_p_o <= '0'; + else + write_fault_p_o <= '0'; + ack_correction <= '0'; + done_w <= '0'; + + case fsm_write is + + when normal_op => + ack_correction <= '0'; + done_w <= '0'; + write_fault_p_o <= '0'; + if (req_correction = '1' and ack_correction = '0') then + q_ram <= f_fix_error (syndrome, d_ram_i); + + we_ram_o <= '1'; + fsm_write <= check_write; + elsif (we = '1') then + q_ram <= f_ecc_word(d); + we_ram_o <= '1'; + fsm_write <= check_write; + end if; + + when check_write => + if (valid_ram_i = '1') then + write_fault_p_o <= '0'; + we_ram_o <= '0'; + + fsm_write <= normal_op; + if (req_correction = '0') then + done_w <= '1'; + else + ack_correction <= '1'; + end if; + end if; + end case; + end if; + end if; + end process; + + +end architecture; \ No newline at end of file diff --git a/hdl/secded_ecc_daec.vhd b/hdl/secded_ecc_daec.vhd new file mode 100644 index 0000000000000000000000000000000000000000..7fcfffdcc671028ea6e60134b989cb3b652c6242 --- /dev/null +++ b/hdl/secded_ecc_daec.vhd @@ -0,0 +1,513 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +--library synplify; +--use synplify.all; +-- +--library smartfusion2; +--use smartfusion2.all; + +entity secded_ecc_daec is + + + + generic ( + g_addr_width : natural := 16 + + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + -- to the processor/bus + d_i : in std_logic_vector(31 downto 0); + a_i : in std_logic_vector(g_addr_width-1 downto 0); + we_i : in std_logic; + bwe_i : in std_logic_vector (3 downto 0); + re_i : in std_logic; + + q_o : out std_logic_vector(31 downto 0); + done_r_o : out std_logic; + done_w_o : out std_logic; + + --to the BRAM + d_ram_i : in std_logic_vector (41 downto 0); + q_ram_o : out std_logic_vector (41 downto 0); + a_ram_o : out std_logic_vector (g_addr_width-1 downto 0); + we_ram_o : out std_logic; + re_ram_o : out std_logic; + valid_ram_i : in std_logic; + lock_req_o : out std_logic; + lock_grant_i : in std_logic; + + + + single_error_p_o : out std_logic; + double_error_p_o : out std_logic; + read_fault_p_o : out std_logic; + write_fault_p_o : out std_logic + ); + + +end secded_ecc_daec; +architecture rtl of secded_ecc_daec is + + + function f_xor (x : std_logic_vector) return std_logic is + variable result : std_logic := '0'; + begin + + for i in x'range loop + result := result xor x(i); + end loop; + return result; + end f_xor; + + function f_or (x : std_logic_vector) return std_logic is + variable result : std_logic := '0'; + begin + + for i in x'range loop + result := result or x(i); + end loop; + return result; + end f_or; + + function f_and (x : std_logic_vector) return std_logic is + variable result : std_logic := '1'; + begin + + for i in x'range loop + result := result and x(i); + end loop; + return result; + end f_and; + +constant syndrome_s1_mask : std_logic_vector (31 downto 0) := "00000000000000000111111111111110"; +constant syndrome_s2_mask : std_logic_vector (31 downto 0) := "00000001000011111000000010101010"; +constant syndrome_s3_mask : std_logic_vector (31 downto 0) := "00000010111101001000000101010011"; +constant syndrome_s4_mask : std_logic_vector (31 downto 0) := "01001100000000010000001000010101"; +constant syndrome_s5_mask : std_logic_vector (31 downto 0) := "00000000101010000001010000000101"; +constant syndrome_s6_mask : std_logic_vector (31 downto 0) := "00101010001000100010010000001000"; +constant syndrome_s7_mask : std_logic_vector (31 downto 0) := "11111000010000010010100001000000"; +constant syndrome_s8_mask : std_logic_vector (31 downto 0) := "01010101100000101101000000100000"; +constant syndrome_s9_mask : std_logic_vector (31 downto 0) := "10010111000110000000100100000000"; +constant syndrome_s10_mask :std_logic_vector (31 downto 0) := "10100000010101000100001010000000"; + + +type array_syndrome is array (0 to 41) of std_logic_vector (9 downto 0); +constant syn_correction_mask : array_syndrome := ( + 0 => "0000011100", + 1 => "0000000111", + 2 => "0000011001", + 3 => "0000100011", + 4 => "0000001101", + 5 => "0010000011", + 6 => "0001000101", + 7 => "1000000011", + 8 => "0100000101", + 9 => "1000001001", + 10=> "0000110001", + 11=> "0101000001", + 12=> "0010010001", + 13=> "0001100001", + 14=> "1010000001", + 15=> "0010000110", + 16=> "0001001010", + 17=> "0010100010", + 18=> "1000000110", + 19=> "0100010010", + 20=> "1100000100", + 21=> "0000110100", + 22=> "1001000100", + 23=> "0010010100", + 24=> "0110000010", + 25=> "0100100100", + 26=> "0110001000", + 27=> "0001101000", + 28=> "0111000000", + 29=> "1001100000", + 30=> "0011001000", + 31=> "1101000000", + 32=> "0000000001", + 33=> "0000000010", + 34=> "0000000100", + 35=> "0000001000", + 36=> "0000010000", + 37=> "0000100000", + 38=> "0001000000", + 39=> "0010000000", + 40=> "0100000000", + 41=> "1000000000"); + +type daec_array_syndrome is array (0 to 20) of std_logic_vector (9 downto 0); +constant daec_syn_correction_mask : daec_array_syndrome := ( + 0 => syn_correction_mask(0) xor syn_correction_mask(1), + 1 => syn_correction_mask(2) xor syn_correction_mask(3), + 2 => syn_correction_mask(4) xor syn_correction_mask(5), + 3 => syn_correction_mask(6) xor syn_correction_mask(7), + 4 => syn_correction_mask(8) xor syn_correction_mask(9), + 5 => syn_correction_mask(10) xor syn_correction_mask(11), + 6 => syn_correction_mask(12) xor syn_correction_mask(13), + 7 => syn_correction_mask(14) xor syn_correction_mask(15), + 8 => syn_correction_mask(16) xor syn_correction_mask(17), + 9 => syn_correction_mask(18) xor syn_correction_mask(19), + 10 => syn_correction_mask(20) xor syn_correction_mask(21), + 11 => syn_correction_mask(22) xor syn_correction_mask(23), + 12 => syn_correction_mask(24) xor syn_correction_mask(25), + 13 => syn_correction_mask(26) xor syn_correction_mask(27), + 14 => syn_correction_mask(28) xor syn_correction_mask(29), + 15 => syn_correction_mask(30) xor syn_correction_mask(31), + 16 => syn_correction_mask(32) xor syn_correction_mask(33), + 17 => syn_correction_mask(34) xor syn_correction_mask(35), + 18 => syn_correction_mask(36) xor syn_correction_mask(37), + 19 => syn_correction_mask(38) xor syn_correction_mask(39), + 20 => syn_correction_mask(40) xor syn_correction_mask(41)); + +function f_calc_syndrome (data: std_logic_vector (41 downto 0)) return std_logic_vector is +variable result : std_logic_vector (9 downto 0); +begin + result (0) := f_xor (data(31 downto 0) and syndrome_s1_mask) xor data(32); + result (1) := f_xor (data(31 downto 0) and syndrome_s2_mask) xor data(33); + result (2) := f_xor (data(31 downto 0) and syndrome_s3_mask) xor data(34); + result (3) := f_xor (data(31 downto 0) and syndrome_s4_mask) xor data(35); + result (4) := f_xor (data(31 downto 0) and syndrome_s5_mask) xor data(36); + result (5) := f_xor (data(31 downto 0) and syndrome_s6_mask) xor data(37); + result (6) := f_xor (data(31 downto 0) and syndrome_s7_mask) xor data(38); + result (7) := f_xor (data(31 downto 0) and syndrome_s8_mask) xor data(39); + result (8) := f_xor (data(31 downto 0) and syndrome_s9_mask) xor data(40); + result (9) := f_xor (data(31 downto 0) and syndrome_s10_mask) xor data(41); +return result; +end f_calc_syndrome; + + +function f_ecc_word (data: std_logic_vector (31 downto 0)) return std_logic_vector is +variable result : std_logic_vector (41 downto 0); +begin +result (31 downto 0) := data; +result (41 downto 32) := f_calc_syndrome ("0000000000" & data); +return result; +end f_ecc_word; + + +function f_ecc_errors (syndrome : std_logic_vector (9 downto 0)) return std_logic is +begin +return f_or (syndrome); +end f_ecc_errors; + +function f_ecc_one_error (syndrome : std_logic_vector (9 downto 0)) return std_logic is +variable syndrome_bound_check : std_logic; +begin +return f_ecc_errors (syndrome) and f_xor (syndrome); +end f_ecc_one_error; + +function f_daec_correctable_errors (syndrome : std_logic_vector (9 downto 0)) return std_logic is +variable result : std_logic := '0'; +begin +for i in 0 to 20 loop + if (syndrome = daec_syn_correction_mask(i)) then + result := '1'; + end if; +end loop; + +return (result); +end f_daec_correctable_errors; + + +function f_fix_daec_errors (syndrome : std_logic_vector (9 downto 0); data: std_logic_vector (41 downto 0)) return std_logic_vector is +variable result : std_logic_vector (41 downto 0) := (others => '1'); +variable mask : std_logic_vector (41 downto 0) := (others => '0'); +variable corrected_word : std_logic_vector (41 downto 0); +begin + +for i in 0 to 20 loop + if (syndrome = daec_syn_correction_mask(i)) then + mask (2*i +1 downto 2*i) := "11"; + end if; +end loop; + +return data xor mask; +end f_fix_daec_errors; + + +function f_fix_error (syndrome : std_logic_vector (9 downto 0); data: std_logic_vector (41 downto 0)) return std_logic_vector is +variable result : std_logic_vector (41 downto 0) := (others => '1'); +variable mask : std_logic_vector (9 downto 0); +variable corrected_word : std_logic_vector (41 downto 0); +begin +for i in 0 to 41 loop + mask := syn_correction_mask(i); + for k in mask'range loop + if (mask (k) = '1') then + result(i) := result(i) and syndrome(k); + end if; + end loop; +end loop; + + +if (f_or (result(31 downto 0)) = '1') then + corrected_word := data (41 downto 32) & (result (31 downto 0) xor data(31 downto 0)); +elsif (f_or (result(41 downto 32)) = '1') then + corrected_word := result xor data; +else + corrected_word := "0000000000" & x"00000000"; +end if; + +return corrected_word; +end f_fix_error; + + + function f_mask_word (mask : std_logic_vector (3 downto 0); d1 : std_logic_vector (31 downto 0); d2 : std_logic_vector (31 downto 0)) return std_logic_vector is + variable masked_word : std_logic_vector (31 downto 0); + begin + for i in 1 to 4 loop + if (mask(i-1) = '0') then + masked_word (i*8-1 downto (i-1)*8) := d2(i*8-1 downto (i-1)*8); + else + masked_word (i*8-1 downto (i-1)*8) := d1(i*8-1 downto (i-1)*8); + end if; + end loop; + return masked_word; + end f_mask_word; + + type fsm_read_states is (normal_op, check_again, wait_lock, wait_correction); + type fsm_write_states is (normal_op, check_write); + type fsm_rw_states is (idle, wait_lock, wait_read, wait_write); + + signal fsm_read : fsm_read_states := normal_op; + signal fsm_write : fsm_write_states := normal_op; + signal fsm_rw : fsm_rw_states := idle; + + + signal ecc_errors, ecc_correctable_error : std_logic; + signal syndrome : std_logic_vector (9 downto 0); + + + signal re_d, re_fsm, we_fsm, re, we, valid_ram_d : std_logic; + signal done_r, done_w, fsm_done_r_p, fsm_done_rw_p : std_logic; + signal lock_req_r, lock_req_rw : std_logic; + signal req_correction, ack_correction : std_logic; + signal fsm_read_normal : std_logic; +signal d, d_rw : std_logic_vector (31 downto 0); + + signal q_ram : std_logic_vector (41 downto 0); + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; +begin + + + + + q_o <= d_ram_i (31 downto 0); + re_ram_o <= '1' when (fsm_read /= normal_op) else re; + + syndrome <= f_calc_syndrome (d_ram_i); + ecc_errors <= f_ecc_errors(syndrome); + ecc_correctable_error <= f_ecc_one_error (syndrome) or f_daec_correctable_errors(syndrome); + + fsm_read_normal <= '1' when fsm_read = normal_op else '0'; + done_r <= (re_d and valid_ram_d and fsm_read_normal and not ecc_errors) or fsm_done_r_p; + done_r_o <= done_r when (fsm_rw = idle) else '0'; + done_w_o <= '1' when (fsm_done_rw_p = '1' or (done_w = '1' and (fsm_rw = idle))) else '0'; + +process (rst_i, a_i, q_ram) + begin + -- synthesis translate_off + + if rst_i = '1' then + a_ram_o <= (others => '0'); + q_ram_o <= (others => '0'); + elsE + -- synthesis translate_on + a_ram_o <= a_i; + q_ram_o <= q_ram; + -- synthesis translate_off +end if; + +-- synthesis translate_on + +end process; + + lock_req_o <= lock_req_r or lock_req_rw; + + + + we <= we_i when (bwe_i = "1111") else we_fsm; + re <= re_i or re_fsm; + d <= d_i when (fsm_rw = idle) else d_rw; + + -- this FSM is used for sub-word writing, which require a word read and a word write + -- the read and write is atomic, dual-port thread-safe + + process (clk_i) + begin + if rising_edge (clk_i) then + if rst_i = '1' then + fsm_rw <= idle; + lock_req_rw <= '0'; + re_fsm <= '0'; + we_fsm <= '0'; + fsm_done_rw_p <= '0'; + else + case (fsm_rw) is + when idle => + fsm_done_rw_p <= '0'; + if (we_i = '1' and fsm_done_rw_p = '0' and bwe_i /= "1111") then + + lock_req_rw <= '1'; + fsm_rw <= wait_lock; + end if; + when wait_lock => + if (lock_grant_i = '1') then + re_fsm <= '1'; + fsm_rw <= wait_read; + end if; + when wait_read => + re_fsm <= '0'; + if (done_r = '1') then + d_rw <= f_mask_word (bwe_i, d_i, d_ram_i (31 downto 0)); + fsm_rw <= wait_write; + we_fsm <= '1'; + end if; + when wait_write => + we_fsm <= '0'; + if (done_w = '1') then + fsm_done_rw_p <= '1'; + lock_req_rw <= '0'; + fsm_rw <= idle; + end if; + when others => + fsm_rw <= idle; + + end case; + end if; + end if; + end process; + + + + process (clk_i) + begin + if rising_edge(clk_i) then + if rst_i = '1' then + fsm_read <= normal_op; + re_d <= '0'; + fsm_done_r_p <= '0'; + lock_req_r <= '0'; + req_correction <= '0'; + single_error_p_o <= '0'; + double_error_p_o <= '0'; + else + re_d <= re; + valid_ram_d <= valid_ram_i; + + case (fsm_read) is + when normal_op => + + --if (re_d = '1' and valid_ram_i = '0') then + -- fsm_read <= busy_ram; + + --els + fsm_done_r_p <= '0'; + single_error_p_o <= '0'; + double_error_p_o <= '0'; + if (re_d = '1' and done_r = '0' and valid_ram_d = '1' and ecc_errors = '1') then + fsm_read <= check_again; + end if; + when check_again => + if (valid_ram_d = '1' and ecc_errors = '1') then + if (ecc_correctable_error = '0') then + double_error_p_o <= '1'; + fsm_done_r_p <= '1'; + fsm_read <= normal_op; + else + lock_req_r <= '1'; + fsm_read <= wait_lock; + end if; + elsif (valid_ram_d = '1' and ecc_errors = '0') then + fsm_read <= normal_op; + end if; + when wait_lock => + if (lock_grant_i = '1') then + req_correction <= '1'; + fsm_read <= wait_correction; + end if; + when wait_correction => + req_correction <= '0'; + if (ack_correction = '1') then + fsm_read <= normal_op; + fsm_done_r_p <= '1'; + single_error_p_o <= '1'; + lock_req_r <= '0'; + end if; + + end case; + end if; + end if; + end process; + + + + + + process (clk_i) + begin + if rising_edge (clk_i) then + if rst_i = '1' then + fsm_write <= normal_op; + done_w <= '0'; + we_ram_o <= '0'; + write_fault_p_o <= '0'; + else + write_fault_p_o <= '0'; + ack_correction <= '0'; + done_w <= '0'; + + case fsm_write is + + when normal_op => + ack_correction <= '0'; + done_w <= '0'; + write_fault_p_o <= '0'; + if (req_correction = '1') then + if (f_ecc_one_error(syndrome) = '1') then + q_ram <= f_fix_error (syndrome, d_ram_i); + else + + q_ram <= f_fix_daec_errors (syndrome, d_ram_i); + end if; + + we_ram_o <= '1'; + fsm_write <= check_write; + elsif (we = '1') then + q_ram <= f_ecc_word(d); + we_ram_o <= '1'; + fsm_write <= check_write; + end if; + + when check_write => + if (valid_ram_i = '1') then + write_fault_p_o <= '0'; + we_ram_o <= '0'; + + -- if (d_ram_i /= q_ram) then + -- write_fault_p_o <= '1'; + -- fsm_write <= check_write; + -- if (write_fault_p_o = '1') then --if write is still wrong, cease + -- done_w <= '1'; --and desist + -- fsm_write <= normal_op; + -- ack_correction <= '1'; + -- end if; + -- else + fsm_write <= normal_op; + done_w <= '1'; + ack_correction <= '1'; + -- end if; + end if; + end case; + end if; + end if; + end process; + + +end architecture; diff --git a/hdl/seu_counters.vhd b/hdl/seu_counters.vhd new file mode 100644 index 0000000000000000000000000000000000000000..b86b2b0786fc38a71f14ded90ad1b57e10e88cf2 --- /dev/null +++ b/hdl/seu_counters.vhd @@ -0,0 +1,81 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; + +--library smartfusion2; +--use smartfusion2.all; + +use work.voter.all; +use work.wb_voter_pkg.all; + + + +entity seu_counters is + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + event_se_iram : in std_logic; + event_de_iram : in std_logic; + event_se_dram : in std_logic; + event_de_dram : in std_logic; + + + se_dram_o : out std_logic_vector (15 downto 0); + de_dram_o : out std_logic_vector (15 downto 0); + + se_iram_o : out std_logic_vector (15 downto 0); + de_iram_o : out std_logic_vector (15 downto 0) + + ); + +end entity seu_counters; + +architecture rtl of seu_counters is + + signal se_iram_counter,de_iram_counter,se_dram_counter,de_dram_counter : unsigned (15 downto 0); + attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + +begin + + se_iram_o <= std_logic_vector(se_iram_counter); + de_iram_o <= std_logic_vector(de_iram_counter); + se_dram_o <= std_logic_vector(se_dram_counter); + de_dram_o <= std_logic_vector(de_dram_counter); + + process (clk_i) + begin + if rising_edge(clk_i) then + if (rst_i = '1') then + se_iram_counter <= (others => '0'); + de_iram_counter <= (others => '0'); + se_dram_counter <= (others => '0'); + de_dram_counter <= (others => '0'); + else + if (event_se_iram = '1') then + se_iram_counter <= se_iram_counter+1; + end if; + if (event_de_iram = '1') then + de_iram_counter <= de_iram_counter+1; + end if; + if (event_se_dram = '1') then + se_dram_counter <= se_dram_counter+1; + end if; + if (event_de_dram = '1') then + de_dram_counter <= de_dram_counter+1; + end if; + end if; + + end if; + end process; + +end architecture; \ No newline at end of file diff --git a/hdl/uart.v b/hdl/uart.v new file mode 100644 index 0000000000000000000000000000000000000000..65b36f10fe9559f6012d39ee6567349bdbdd2326 --- /dev/null +++ b/hdl/uart.v @@ -0,0 +1,104 @@ +`define BAUD_RATE 115200 +`define SCALER (50000000 / `BAUD_RATE) + +module uart +( + input reset_i, /* synthesis syn_keep = 1 */ + input clk_i, /* synthesis syn_keep = 1 */ + output txd_o, /* synthesis syn_keep = 1 */ + input [7:0] tx_data_i, /* synthesis syn_keep = 1 */ + output reg tx_wdone_o, /* synthesis syn_preserve = 1 */ + output reg tx_ready_o, + input tx_req_i /* synthesis syn_keep = 1 */ +)/* synthesis syn_radhardlevel="tmr" */; + +parameter S0 = 0; +parameter S1 = 1; +parameter S2 = 2; +parameter S3 = 3; + + + + +/**********************************/ +/* TX */ +/**********************************/ + +reg clk_tx; /* synthesis syn_preserve = 1 */ +reg clk_tx_en; /* synthesis syn_preserve = 1 */ +reg [15:0] tx_div; /* synthesis syn_preserve = 1 */ +reg [7:0] tx_data_acq; /* synthesis syn_preserve = 1 */ +always@(posedge clk_i) +begin + clk_tx <= 'b0; + if (clk_tx_en) begin + tx_div <= tx_div + 1; + if (tx_div == `SCALER) begin + clk_tx <= 1'b1; + tx_div <= 'b0; + end + end + else tx_div <= 'b0; +end + +integer tx_state /* synthesis syn_encoding="onehot" */; +reg [10:0] tx_data; /* synthesis syn_preserve = 1 */ +reg [4:0] tx_data_cnt; /* synthesis syn_preserve = 1 */ + +always@(posedge reset_i or posedge clk_i) +begin + if (reset_i) begin + tx_state <= S0; + tx_data <= {11{1'b1}}; + tx_wdone_o <= 1'b0; + clk_tx_en <= 1'b0; + tx_data_cnt <= 'b0; + tx_ready_o <= 1'b0; + end + else case (tx_state) + S0: begin + tx_wdone_o <= 1'b0; + tx_ready_o <= 1'b1; + if (tx_req_i & tx_ready_o) begin + tx_state <= S1; + tx_wdone_o <= 1'b1; + tx_data_acq <= tx_data_i; + tx_ready_o <= 1'b0; + + + end + + end + + S1: begin + tx_state <= S2; + tx_ready_o <= 1'b0; + tx_wdone_o <= 1'b0; + end + + S2: begin + tx_data <= {1'b1, tx_data_acq, 2'b01}; + clk_tx_en <= 1'b1; + tx_state <= S3; + end + + S3: begin + if (clk_tx) begin + tx_data <= {1'b0, tx_data[10:1]}; + tx_data_cnt <= tx_data_cnt + 1; + if (tx_data_cnt == 9) begin + tx_data_cnt <= 'b0; + tx_state <= S0; + clk_tx_en <= 1'b0; + end + end + end + + + default: tx_state <= S0; + endcase +end + +assign txd_o = tx_data[0]; + +endmodule diff --git a/hdl/ueth.vhd b/hdl/ueth.vhd new file mode 100644 index 0000000000000000000000000000000000000000..c1351fd10ad86b202992ee6aa2daec0d45cc81a3 --- /dev/null +++ b/hdl/ueth.vhd @@ -0,0 +1,230 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity ueth is + + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + --TX + phy0_tx_clk_i : in std_logic; + phy0_txd_o : out std_logic_vector (3 downto 0); + phy0_txen_o : out std_logic; + --RX + phy0_rx_clk_i : in std_logic; + phy0_rxd_i : in std_logic_vector (3 downto 0); + phy0_rxdv_i : in std_logic; + phy0_rxerr_i : in std_logic; + + --TX + phy1_tx_clk_i : in std_logic; + phy1_txd_o : out std_logic_vector (3 downto 0); + phy1_txen_o : out std_logic; + --RX + phy1_rx_clk_i : in std_logic; + phy1_rxd_i : in std_logic_vector (3 downto 0); + phy1_rxdv_i : in std_logic; + phy1_rxerr_i : in std_logic; + + + --MIIM + phy_mdc_o : out std_logic; + phy_md_i : in std_logic; + phy_md_o : out std_logic; + phy_oe_o : out std_logic; + + irq_o : out std_logic; + phy_rst_o : out std_logic; + -- to the Wishbone xbar + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + master_o : out t_wishbone_master_out; + master_i : in t_wishbone_master_in + + ); +end entity ueth; + + +architecture rtl of ueth is + +signal rst_phy, phy_rxen, phy_txen : std_logic; +signal mac_rxd, mac_txd, hub_phy0_txd, hub_phy0_rxd, hub_phy1_txd, hub_phy1_rxd : std_logic_vector (3 downto 0); +signal mac_rx_valid, mac_tx_valid, mac_tx_ready, mac_rx_eof, mac_tx_eof : std_logic; + +signal hub_phy0_txdv, hub_phy0_tx_ready, hub_phy0_rxdv, hub_phy0_rx_ready : std_logic; +signal hub_phy1_txdv, hub_phy1_tx_ready, hub_phy1_rxdv, hub_phy1_rx_ready : std_logic; + +signal hub_phy0_rx_eof, hub_phy1_rx_eof : std_logic; + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + + + + +begin + +phy_rst_o <= rst_phy; + +inst_mac : entity work.ueth_mac + + + port map( + + + clk_i => clk_i, + rst_i => rst_i, + + rst_phy_o => rst_phy, + phy_rxen_o => phy_rxen, + phy_txen_o => phy_txen, + + mac_rxd_i => mac_rxd, + mac_txd_o => mac_txd, + mac_rx_valid_i => mac_rx_valid, + mac_tx_valid_o => mac_tx_valid, + mac_tx_ready_i => mac_tx_ready, + mac_rx_eof_i => mac_rx_eof, + mac_tx_eof_o => mac_tx_eof, + + irq_o => irq_o, + + slave_i => slave_i, + slave_o => slave_o, + + master_o => master_o, + master_i => master_i, + + -- MIIM + phy_mdc_o => phy_mdc_o, + phy_md_i => phy_md_i, + phy_md_o => phy_md_o, + phy_oe_o => phy_oe_o + ); + + + + +inst_hub : entity work.ueth_hub + + + port map ( + + + phy0_txd_o => hub_phy0_txd, + phy0_tx_valid_o => hub_phy0_txdv, + phy0_tx_ready_i => hub_phy0_tx_ready, + phy0_rxd_i => hub_phy0_rxd, + phy0_rx_valid_i => hub_phy0_rxdv, + phy0_rx_ready_o => hub_phy0_rx_ready, -- backpressure + phy0_rx_eof_i => hub_phy0_rx_eof, + + phy1_txd_o => hub_phy1_txd, + phy1_tx_valid_o => hub_phy1_txdv, + phy1_tx_ready_i => hub_phy1_tx_ready, + phy1_rxd_i => hub_phy1_rxd, + phy1_rx_valid_i => hub_phy1_rxdv, + phy1_rx_ready_o => hub_phy1_rx_ready, -- backpressure + phy1_rx_eof_i => hub_phy1_rx_eof, + + mac_txd_i => mac_txd, + mac_rxd_o => mac_rxd, + mac_tx_valid_i => mac_tx_valid, + mac_rx_valid_o => mac_rx_valid, + mac_tx_ready_o => mac_tx_ready, -- backpressure + mac_rx_eof_o => mac_rx_eof, + mac_tx_eof_i => mac_tx_eof, + + clk_i => clk_i, + rst_i => rst_i + + ); + +inst_eth_phy0 : entity work.ueth_uphy + port map ( + + clk_i => clk_i, + rst_i => rst_i or rst_phy, + rx_en_i => phy_rxen, + + + rxd_o => hub_phy0_rxd, + rxdv_o => hub_phy0_rxdv, + rx_ready_i => hub_phy0_rx_ready, + rx_eof_o => hub_phy0_rx_eof, + + txd_i => hub_phy0_txd, + txdv_i => hub_phy0_txdv, + tx_ready_o => hub_phy0_tx_ready, + + + --PHY TX + phy_tx_clk_i => phy0_tx_clk_i, + phy_txd_o => phy0_txd_o, + phy_txen_o => phy0_txen_o, + + --PHY RX + phy_rx_clk_i => phy0_rx_clk_i, + phy_rxd_i => phy0_rxd_i, + phy_rxdv_i => phy0_rxdv_i, + phy_rxerr_i => phy0_rxerr_i + ); + + + + + + +inst_eth_phy1 : entity work.ueth_uphy + port map ( + + clk_i => clk_i, + rst_i => rst_i or rst_phy, + rx_en_i => phy_rxen, + + + rxd_o => hub_phy1_rxd, + rxdv_o => hub_phy1_rxdv, + rx_ready_i => hub_phy1_rx_ready, + rx_eof_o => hub_phy1_rx_eof, + + txd_i => hub_phy1_txd, + txdv_i => hub_phy1_txdv, + tx_ready_o => hub_phy1_tx_ready, + + + --PHY TX + phy_tx_clk_i => phy1_tx_clk_i, + phy_txd_o => phy1_txd_o, + phy_txen_o => phy1_txen_o, + + --PHY RX + phy_rx_clk_i => phy1_rx_clk_i, + phy_rxd_i => phy1_rxd_i, + phy_rxdv_i => phy1_rxdv_i, + phy_rxerr_i => phy1_rxerr_i + ); + + + + + + + + + end architecture; + diff --git a/hdl/ueth_crc.vhd b/hdl/ueth_crc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..c4ef40809cd9031ee298dfbb556da0ee75ed3714 --- /dev/null +++ b/hdl/ueth_crc.vhd @@ -0,0 +1,96 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity ueth_crc is + + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + en_i : in std_logic; + data_i : in std_logic_vector (3 downto 0); + crc_o : out std_logic_vector (31 downto 0) + ); + end entity ueth_crc; + + architecture rtl of ueth_crc is + signal crc : std_logic_vector (31 downto 0); + signal data : std_logic_vector (3 downto 0); + + + attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + + begin + +data <= data_i; + + process (clk_i) + begin + if rising_edge (clk_i) then + if (rst_i = '1') then + crc <= (others => '1'); + elsif (en_i = '1') then + crc(0) <= crc(28) xor data(3); + crc(1) <= crc(28) xor crc(29) xor data(2) xor data(3); + crc(2) <= crc(28) xor crc(29) xor crc(30) xor data(1) xor data(2) xor data(3); + crc(3) <= crc(29) xor crc(30) xor crc(31) xor data(0) xor data(1) xor data(2); + crc(4) <= crc(0) xor crc(28) xor crc(30) xor crc(31) xor data(0) xor data(1) xor data(3); + crc(5) <= crc(1) xor crc(28) xor crc(29) xor crc(31) xor data(0) xor data(2) xor data(3); + crc(6) <= crc(2) xor crc(29) xor crc(30) xor data(1) xor data(2); + crc(7) <= crc(3) xor crc(28) xor crc(30) xor crc(31) xor data(0) xor data(1) xor data(3); + crc(8) <= crc(4) xor crc(28) xor crc(29) xor crc(31) xor data(0) xor data(2) xor data(3); + crc(9) <= crc(5) xor crc(29) xor crc(30) xor data(1) xor data(2); + crc(10) <= crc(6) xor crc(28) xor crc(30) xor crc(31) xor data(0) xor data(1) xor data(3); + crc(11) <= crc(7) xor crc(28) xor crc(29) xor crc(31) xor data(0) xor data(2) xor data(3); + crc(12) <= crc(8) xor crc(28) xor crc(29) xor crc(30) xor data(1) xor data(2) xor data(3); + crc(13) <= crc(9) xor crc(29) xor crc(30) xor crc(31) xor data(0) xor data(1) xor data(2); + crc(14) <= crc(10) xor crc(30) xor crc(31) xor data(0) xor data(1); + crc(15) <= crc(11) xor crc(31) xor data(0); + crc(16) <= crc(12) xor crc(28) xor data(3); + crc(17) <= crc(13) xor crc(29) xor data(2); + crc(18) <= crc(14) xor crc(30) xor data(1); + crc(19) <= crc(15) xor crc(31) xor data(0); + crc(20) <= crc(16); + crc(21) <= crc(17); + crc(22) <= crc(18) xor crc(28) xor data(3); + crc(23) <= crc(19) xor crc(28) xor crc(29) xor data(2) xor data(3); + crc(24) <= crc(20) xor crc(29) xor crc(30) xor data(1) xor data(2); + crc(25) <= crc(21) xor crc(30) xor crc(31) xor data(0) xor data(1); + crc(26) <= crc(22) xor crc(28) xor crc(31) xor data(0) xor data(3); + crc(27) <= crc(23) xor crc(29) xor data(2); + crc(28) <= crc(24) xor crc(30) xor data(1); + crc(29) <= crc(25) xor crc(31) xor data(0); + crc(30) <= crc(26); + crc(31) <= crc(27); + + end if; + end if; + end process; + + + crc_o <= crc; + + + + + + + + + + + end architecture; diff --git a/hdl/ueth_dma.vhd b/hdl/ueth_dma.vhd new file mode 100644 index 0000000000000000000000000000000000000000..d38a4396d62ba265f1d9533d557f6a95b2f00165 --- /dev/null +++ b/hdl/ueth_dma.vhd @@ -0,0 +1,529 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity ueth_dma is + + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + rx_en_o : out std_logic; + tx_en_o : out std_logic; + rx_ready_o : out std_logic; + + rx_done_i : in std_logic; + tx_done_i : in std_logic; + rx_overflow_i : in std_logic; + tx_underflow_i : in std_logic; + + tx_pending_o : out std_logic; + rx_pending_o : out std_logic; + + tx_fifo_data_o : out std_logic_vector (35 downto 0); + tx_fifo_valid_o : out std_logic; + tx_fifo_ready_i : in std_logic; + -- tx_fifo_last_o : out std_logic; + + rx_fifo_data_i : in std_logic_vector (35 downto 0); + rx_fifo_valid_i : in std_logic; + rx_fifo_ready_o : out std_logic; + rx_fifo_eof_i : in std_logic; + + irq_o : out std_logic; + + mii_rd_o : out std_logic; + mii_done_i : in std_logic; + mii_addr_o : out std_logic_vector (4 downto 0); + mii_reg_i : in std_logic_vector (15 downto 0); + + + rst_mac_o : out std_logic; + + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + + master_o : out t_wishbone_master_out; + master_i : in t_wishbone_master_in + + ); +end entity ueth_dma; + + +architecture rtl of ueth_dma is + + type r_descriptor is record + int_flag : std_logic; + size : unsigned (10 downto 0); + addr : std_logic_vector (15 downto 0); + busy : std_logic; + fifo_flow_error : std_logic; + end record r_descriptor; + + function f_byte_count (byte_sel : std_logic_vector (3 downto 0)) return integer is + begin + case (byte_sel) is + when "0001" => return 1; + when "0011" => return 2; + when "0111" => return 3; + when "1111" => return 4; + when others => return 0; + end case; + end f_byte_count; + + function f_byte_sel (byte_counter : unsigned (1 downto 0)) return std_logic_vector is + begin + case (to_integer (byte_counter)) is + when 0 => return "1111"; + when 1 => return "0001"; + when 2 => return "0011"; + when 3 => return "0111"; + when others => return "XXXX"; + end case; + end f_byte_sel; + + + constant c_ETHERTYPE_POWERLINK : std_logic_vector (15 downto 0) := x"ab88"; + constant rx_descriptor0_addr : std_logic_vector (15 downto 0) := x"f400"; + constant rx_descriptor1_addr : std_logic_vector (15 downto 0) := x"f9ec"; + + type t_fsm_rx is (idle, setup, read_word, write_word); + type t_fsm_tx is (idle, read_word, write_word, write_partial_word, wait_tx_done); + type t_fsm_dma is (idle, transfer_read, transfer_write); + + signal fsm_rx : t_fsm_rx := idle; + signal fsm_tx : t_fsm_tx := idle; + signal fsm_dma : t_fsm_dma := idle; + + signal last_word : std_logic; + signal rx_descriptor0, rx_descriptor1, tx_descriptor : r_descriptor; + signal tx_enable, rx_enable, mii_scrubber_enable : std_logic; + signal peding_tx, pending_rx : std_logic; + signal dma_write, dma_read : std_logic; + signal read_addr, write_addr : unsigned (15 downto 0); + signal dma_write_bsel : std_logic_vector (3 downto 0); + signal tx_pkt_sent_p, rx_pkt_recv_p : std_logic; + signal tx_bytes, rx_bytes : unsigned (10 downto 0); + signal dma_read_req, dma_read_done, dma_write_req, dma_write_done : std_logic; + signal data_tx, data_rx : std_logic_vector (31 downto 0); + signal rx_desc_taken : std_logic; + signal rx_ethertype : std_logic_vector(15 downto 0); + +signal mii_read_p, mii_done : std_logic; +signal mii_reg : std_logic_vector (15 downto 0); + +signal dma_read_write : std_logic; + +signal mac_rx_timeout : unsigned (5 downto 0); + +attribute syn_encoding : string; +attribute syn_encoding of fsm_rx, fsm_tx, fsm_dma : signal is "safe,onehot"; + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; +begin + + irq_o <= rx_descriptor0.int_flag or rx_descriptor1.int_flag or tx_descriptor.int_flag; + + rx_en_o <= rx_enable; + tx_en_o <= tx_enable; + + rx_ready_o <= (rx_descriptor0.busy or rx_descriptor1.busy) and not rx_pending_o; + + rx_descriptor0.addr <= rx_descriptor0_addr; + rx_descriptor1.addr <= rx_descriptor1_addr; + + tx_descriptor.fifo_flow_error <= tx_underflow_i; + + slave_o.stall <= (not slave_o.ack) and slave_i.cyc and slave_i.stb; + + process (clk_i) + begin + + if rising_edge (clk_i) then + if (rst_i) then + tx_enable <= '0'; + rx_enable <= '0'; + rx_descriptor0.busy <= '0'; + rx_descriptor1.busy <= '0'; + tx_descriptor.busy <= '0'; + rx_descriptor0.int_flag <= '0'; + rx_descriptor1.int_flag <= '0'; + tx_descriptor.int_flag <= '0'; + mii_rd_o <= '0'; + rst_mac_o <= '1'; + + + else + slave_o.ack <= '0'; + mii_rd_o <= '0'; + if (slave_i.stb = '1' and slave_i.cyc = '1' and slave_o.ack = '0') then + slave_o.ack <= '1'; + if (slave_i.adr(4 downto 2) = "000") then + slave_o.dat (31) <= rx_descriptor0.busy; + slave_o.dat (30) <= rx_descriptor0.fifo_flow_error; + slave_o.dat (29) <= rx_descriptor0.int_flag; + slave_o.dat (26 downto 16) <= std_logic_vector(rx_descriptor0.size); + slave_o.dat (15 downto 0) <= (rx_descriptor0.addr); + rx_descriptor0.int_flag <= '0'; + if (slave_i.we = '1') then + -- rx_descriptor0.int_flag <= slave_o.dat (29); + if (rx_descriptor0.busy = '0') then + rx_descriptor0.busy <= slave_i.dat(31); + --rx_descriptor.size <= unsigned(slave_i.dat (10 downto 0)); + end if; + end if; + elsif (slave_i.adr(4 downto 2) = "001") then + slave_o.dat (31) <= rx_descriptor1.busy; + slave_o.dat (30) <= rx_descriptor1.fifo_flow_error; + slave_o.dat (29) <= rx_descriptor1.int_flag; + slave_o.dat (26 downto 16) <= std_logic_vector(rx_descriptor1.size); + slave_o.dat (15 downto 0) <= (rx_descriptor1.addr); + rx_descriptor1.int_flag <= '0'; + if (slave_i.we = '1') then + -- rx_descriptor1.int_flag <= slave_o.dat (29); + if (rx_descriptor1.busy = '0') then + rx_descriptor1.busy <= slave_i.dat(31); + --rx_descriptor.size <= unsigned(slave_i.dat (10 downto 0)); + end if; + end if; + elsif (slave_i.adr(4 downto 2) = "010") then + slave_o.dat (31) <= tx_descriptor.busy; + slave_o.dat (30) <= tx_descriptor.fifo_flow_error; + slave_o.dat (29) <= tx_descriptor.int_flag; + slave_o.dat (26 downto 16) <= std_logic_vector(tx_descriptor.size); --( + slave_o.dat (15 downto 0) <= tx_descriptor.addr; -- + tx_descriptor.int_flag <= '0'; + if (slave_i.we = '1') then + if (tx_descriptor.busy = '0') then + tx_descriptor.busy <= slave_i.dat(31); + tx_descriptor.size <= unsigned(slave_i.dat (26 downto 16)); + tx_descriptor.addr <= slave_i.dat(15 downto 0); + end if; + end if; + elsif (slave_i.adr(4 downto 2) = "011") then + + slave_o.dat (31 downto 3) <= (others => '0'); + slave_o.dat (2 downto 0) <= rst_mac_o & tx_enable & rx_enable; + + if (slave_i.we = '1') then + rst_mac_o <= slave_i.dat(3); + tx_enable <= slave_i.dat(1); + rx_enable <= slave_i.dat(0); + if (slave_i.dat(2) = '1') then + tx_enable <= '0'; + rx_enable <= '0'; + end if; + end if; + elsif (slave_i.adr(4 downto 2) = "100") then + if (slave_i.we = '1') then + mii_addr_o <= slave_i.dat(4 downto 0); + mii_rd_o <= '1'; + end if; + elsif (slave_i.adr(4 downto 2) = "101") then + slave_o.dat (31) <= mii_done_i; + slave_o.dat (30 downto 16) <= (others => '0'); + slave_o.dat (15 downto 0) <= mii_reg_i; + end if; + end if; + if (rx_pkt_recv_p = '1' and rx_desc_taken = '0') then + rx_descriptor0.busy <= '0'; + rx_descriptor0.int_flag <= '1'; + end if; + if (rx_pkt_recv_p = '1' and rx_desc_taken = '1') then + rx_descriptor1.busy <= '0'; + rx_descriptor1.int_flag <= '1'; + end if; + if (tx_pkt_sent_p = '1') then + tx_descriptor.busy <= '0'; + tx_descriptor.int_flag <= '1'; + end if; + + + end if; + end if; + end process; + +-- rx flux + + process (clk_i) + begin + if rising_edge (clk_i) then + if (rst_i) then + fsm_rx <= idle; + rx_descriptor0.fifo_flow_error <= '0'; + rx_descriptor1.fifo_flow_error <= '0'; + rx_descriptor0.size <= (others => '0'); + rx_descriptor1.size <= (others => '0'); + dma_write_req <= '0'; + rx_pending_o <= '0'; + mac_rx_timeout <= (others => '0'); + else + rx_pkt_recv_p <= '0'; + case (fsm_rx) is + when idle => + rx_pending_o <= '0'; + rx_fifo_ready_o <= '0'; + if (rx_fifo_valid_i = '1' and rx_enable = '1' and rx_done_i = '0' and ((rx_descriptor0.busy = '1' or rx_descriptor1.busy = '1') and rx_pkt_recv_p = '0')) then + fsm_rx <= read_word; + if (rx_descriptor0.busy = '1') then + write_addr <= unsigned(rx_descriptor0.addr); + rx_desc_taken <= '0'; + else + write_addr <= unsigned(rx_descriptor1.addr); + rx_desc_taken <= '1'; + end if; + rx_pending_o <= '1'; + rx_bytes <= (others => '0'); + end if; + + when read_word => + rx_fifo_ready_o <= '0'; + if (rx_fifo_valid_i = '1' and rx_fifo_eof_i = '0') then + rx_fifo_ready_o <= '1'; + + data_rx <= rx_fifo_data_i (31 downto 0); + dma_write_req <= '1'; + fsm_rx <= write_word; + dma_write_bsel <= rx_fifo_data_i (35 downto 32); + rx_bytes <= rx_bytes + f_byte_count (rx_fifo_data_i (35 downto 32)); + + if (rx_bytes = to_unsigned(12, 11)) then + rx_ethertype <= rx_fifo_data_i (15 downto 0); + end if; + end if; + if (rx_fifo_valid_i = '1' and rx_fifo_eof_i = '1') then + fsm_rx <= idle; + rx_fifo_ready_o <= '1'; + -- if (rx_ethertype = c_ETHERTYPE_POWERLINK) then --If a tree falls in a forest and no one is around to hear it, does it make a sound? + rx_pkt_recv_p <= '1'; + -- end if; + if (rx_desc_taken = '0') then + rx_descriptor0.size <= rx_bytes; + rx_descriptor0.fifo_flow_error <= rx_overflow_i; + else + rx_descriptor1.size <= rx_bytes; + rx_descriptor1.fifo_flow_error <= rx_overflow_i; + end if; + end if; + + -- timeout if EOF flag is corrupted + if (rx_fifo_valid_i = '1') then + mac_rx_timeout <= (others => '0'); + else + mac_rx_timeout <= mac_rx_timeout + 1; + if (mac_rx_timeout (5)) then + fsm_rx <= idle; + end if; + end if; + + + when write_word => + rx_fifo_ready_o <= '0'; + if (dma_write_done = '1') then + dma_write_req <= '0'; + write_addr <= write_addr + 4; + fsm_rx <= read_word; + + + + end if; + when others => + fsm_rx <= idle; + + end case; + end if; + end if; + end process; + + -- tx flux + + process (clk_i) + begin + if rising_edge (clk_i) then + if (rst_i) then + fsm_tx <= idle; + dma_read_req <= '0'; + tx_fifo_valid_o <= '0'; + else + tx_pkt_sent_p <= '0'; + case (fsm_tx) is + when idle => + tx_pending_o <= '0'; + if (tx_enable = '1' and (tx_descriptor.busy = '1' and tx_pkt_sent_p = '0')) then + fsm_tx <= read_word; + read_addr <= unsigned(tx_descriptor.addr); + tx_bytes <= (others => '0'); + + end if; + + when read_word => + + + if (tx_bytes (10 downto 2) >= tx_descriptor.size (10 downto 2)) then + if (tx_descriptor.size (1 downto 0) = 0) then + fsm_tx <= idle; + tx_pkt_sent_p <= '1'; + tx_pending_o <= '0'; + + else + dma_read_req <= '1'; + fsm_tx <= write_partial_word; + end if; + elsif (tx_fifo_ready_i = '1') then + dma_read_req <= '1'; + fsm_tx <= write_word; + + end if; + + when write_word => + --dma_read_req <= '0'; + --tx_fifo_last_o <= '0'; + if (dma_read_done = '1' ) then + dma_read_req <= '0'; + + tx_fifo_valid_o <= '1'; + tx_fifo_data_o <= "1111" & data_tx; + read_addr <= read_addr + 4; + tx_bytes <= tx_bytes + 4; + end if; + if (tx_fifo_valid_o = '1' and tx_fifo_ready_i = '1') then + fsm_tx <= read_word; + tx_fifo_valid_o <= '0'; + end if; + + + if (tx_bytes (4) = '1') then + tx_pending_o <= '1'; + + end if; + when write_partial_word => + --dma_read_req <= '0'; + if (dma_read_done = '1') then + dma_read_req <= '0'; + + + tx_fifo_valid_o <= '1'; + tx_fifo_data_o <= f_byte_sel(tx_descriptor.size(1 downto 0)) & data_tx; + read_addr <= read_addr + 4; + tx_bytes <= tx_bytes + tx_descriptor.size (1 downto 0); + end if; + if (tx_fifo_valid_o = '1' and tx_fifo_ready_i = '1') then + fsm_tx <= idle; + tx_pkt_sent_p <= '1'; + tx_pending_o <= '0'; + tx_fifo_valid_o <= '0'; + end if; + + + when wait_tx_done => + if (tx_done_i = '1') then + fsm_tx <= idle; + end if; + + when others => + fsm_tx <= idle; + + end case; + end if; + end if; + end process; + + master_o.adr(31 downto 16) <= x"8500"; +dma_write <= dma_write_req and not dma_write_done; +dma_read <= dma_read_req and not dma_read_done; + process (clk_i) + begin + if rising_edge(clk_i) then + if (rst_i) then + fsm_dma <= idle; + master_o.cyc <= '0'; + master_o.stb <= '0'; + dma_read_done <= '0'; + dma_write_done <= '0'; + dma_read_write <= '0'; -- read = 1 + else + case (fsm_dma) is + + when idle => + dma_write_done <= '0'; + dma_read_done <= '0'; + if (dma_write = '1' and dma_read = '1') then + dma_read_write <= not dma_read_write; + if (dma_read_write = '1') then + fsm_dma <= transfer_write; + else + fsm_dma <= transfer_read; + end if; + elsif (dma_write = '1' or dma_read = '1') then + if (dma_write = '1') then + fsm_dma <= transfer_write; + dma_read_write <= '0'; + else + fsm_dma <= transfer_read; + dma_read_write <= '1'; + end if; + + + end if; + when transfer_read => + master_o.cyc <= '1'; + master_o.stb <= '1'; + master_o.we <= '0'; + master_o.sel <= "1111" ; + master_o.adr (15 downto 0) <= std_logic_vector(read_addr); + master_o.dat <= data_rx; + + + data_tx <= master_i.dat; + + if (master_i.ack = '1') then + master_o.cyc <= '0'; + master_o.stb <= '0'; + + dma_read_done <= '1'; + fsm_dma <= idle; + + end if; + + when transfer_write => + master_o.cyc <= '1'; + master_o.stb <= '1'; + master_o.we <= '1'; + master_o.sel <= dma_write_bsel; + master_o.adr (15 downto 0) <= std_logic_vector(write_addr); + master_o.dat <= data_rx; + + + if (master_i.ack = '1') then + master_o.cyc <= '0'; + master_o.stb <= '0'; + dma_write_done <= '1'; + + fsm_dma <= idle; + + end if; + + when others => + fsm_dma <= idle; + end case; + end if; + end if; + end process; + + + + end architecture; diff --git a/hdl/ueth_hub.vhd b/hdl/ueth_hub.vhd new file mode 100644 index 0000000000000000000000000000000000000000..d56c63a717458936613fde1b81e9c38a10f34b61 --- /dev/null +++ b/hdl/ueth_hub.vhd @@ -0,0 +1,261 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + + + +entity ueth_hub is + + + port ( + + + phy0_txd_o : out std_logic_vector (3 downto 0); + phy0_tx_valid_o : out std_logic; + phy0_tx_ready_i : in std_logic; + phy0_rxd_i : in std_logic_vector (3 downto 0); + phy0_rx_valid_i: in std_logic; + phy0_rx_ready_o : out std_logic; + phy0_rx_eof_i : in std_logic; + + + + + phy1_txd_o : out std_logic_vector (3 downto 0); + phy1_tx_valid_o : out std_logic; + phy1_tx_ready_i : in std_logic; + phy1_rxd_i : in std_logic_vector (3 downto 0); + phy1_rx_valid_i: in std_logic; + phy1_rx_ready_o : out std_logic; + phy1_rx_eof_i : in std_logic; + + + + mac_txd_i : in std_logic_vector (3 downto 0); + mac_rxd_o : out std_logic_vector (3 downto 0); + mac_tx_valid_i : in std_logic; + mac_rx_valid_o : out std_logic; + mac_tx_ready_o : out std_logic; + mac_tx_eof_i : in std_logic; + mac_rx_eof_o : out std_logic; + + clk_i : in std_logic; + rst_i : in std_logic + + ); + + + end entity ueth_hub; + + architecture rtl of ueth_hub is + + + type mux_states is (connect_none, connect_mac, connect_phy0, connect_phy1); + signal mux_phy0, mux_phy1, mux_mac : mux_states; + + type fsm_tx_states is (idle, wait_channel, wait_send, wait_ifg); + signal fsm_mac_tx : fsm_tx_states := idle; + type fsm_rx_states is (idle, wait_phy0_rx, wait_phy1_rx); + signal fsm_mac_rx : fsm_rx_states := idle; + + signal phy0_rxd_d, phy1_rxd_d : std_logic_vector (3 downto 0); + signal phy0_rx_valid_d, phy1_rx_valid_d, phy0_rx_valid_d2, phy1_rx_valid_d2 : std_logic; +signal phy0_rx_eof_d, phy1_rx_eof_d : std_logic; + signal ifg_count : unsigned (7 downto 0); + signal ifg_good : std_logic; + + + attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + + begin + + --backpressure to be used with preamble insertion option + phy0_rx_ready_o <= '1'; + phy1_rx_ready_o <= '1'; + + --mux phy0 + + process (mux_phy0, phy1_rxd_i, mac_txd_i, phy1_rx_valid_i, mac_tx_valid_i, mac_tx_ready_o, phy1_rx_eof_i) + begin + if mux_phy0 = connect_phy1 then + phy0_txd_o <= phy1_rxd_i; + phy0_tx_valid_o <= phy1_rx_valid_i and not phy1_rx_eof_i; + elsif mux_phy0 = connect_mac then + phy0_txd_o <= mac_txd_i; + phy0_tx_valid_o <= mac_tx_valid_i and mac_tx_ready_o; -- and phy0_tx_ready_i; + else + phy0_txd_o <= (others => '0'); + phy0_tx_valid_o <= '0'; + end if; + end process; + + -- mux phy1 + + process (mux_phy1, phy0_rxd_i, phy0_rx_valid_i, mac_txd_i, mac_tx_valid_i, mac_tx_ready_o, phy0_rx_eof_i) + begin + if mux_phy1 = connect_phy0 then + phy1_txd_o <= phy0_rxd_i; + phy1_tx_valid_o <= phy0_rx_valid_i and not phy0_rx_eof_i; + elsif mux_phy1 = connect_mac then + phy1_txd_o <= mac_txd_i; + phy1_tx_valid_o <= mac_tx_valid_i and mac_tx_ready_o;-- and phy1_tx_ready_i; + else + phy1_txd_o <= (others => '0'); + phy1_tx_valid_o <= '0'; + end if; + end process; + + + -- mux mac + + process (mux_mac, phy0_rxd_d, phy1_rxd_d, phy0_rx_valid_d, phy1_rx_valid_d, phy0_rx_eof_i, phy1_rx_eof_i) + begin + if mux_mac= connect_phy0 then + mac_rxd_o <= phy0_rxd_d; + mac_rx_valid_o <= phy0_rx_valid_d; + mac_rx_eof_o <= phy0_rx_eof_d; + elsif mux_mac = connect_phy1 then + mac_rxd_o <= phy1_rxd_d; + mac_rx_valid_o <= phy1_rx_valid_d; + mac_rx_eof_o <= phy1_rx_eof_d; + else + mac_rxd_o <= (others => '0'); + mac_rx_valid_o <= '0'; + mac_rx_eof_o <= '0'; + end if; + end process; + +process (clk_i) +begin + if rising_edge(clk_i) then + phy0_rx_valid_d <= phy0_rx_valid_i; + phy0_rx_valid_d2 <= phy0_rx_valid_d; + phy0_rxd_d <= phy0_rxd_i; + phy1_rx_valid_d <= phy1_rx_valid_i; + phy1_rx_valid_d2 <= phy1_rx_valid_d; + phy1_rxd_d <= phy1_rxd_i; + phy0_rx_eof_d <= phy0_rx_eof_i; + phy1_rx_eof_d <= phy1_rx_eof_i; +end if; +end process; + + process (clk_i) + begin + if rising_edge(clk_i) then + if rst_i = '1' then + ifg_count <= (others => '0'); + ifg_good <= '0'; + else + if (phy0_tx_valid_o = '1' or phy1_tx_valid_o = '1') then + ifg_count <= (others => '0'); + ifg_good <= '0'; + elsif ifg_count < x"C0" then + ifg_count <= ifg_count + 1; + ifg_good <= '0'; + else + ifg_good <= '1'; + end if; + end if; + end if; +end process; + + + mac_tx_ready_o <= phy0_tx_ready_i and phy1_tx_ready_i when (fsm_mac_tx = wait_send) else '0'; + + process (clk_i) + begin + if rising_edge(clk_i) then + case (fsm_mac_tx) is + when idle=> + -- safely connect the PHYs TX/RX (i.e. do not connect in the middle of a frame) + if (phy0_rx_valid_i = '0' and phy0_rx_valid_d = '0') then + mux_phy1 <= connect_phy0; + end if; + if (phy1_rx_valid_i = '0' and phy1_rx_valid_d = '0') then + mux_phy0 <= connect_phy1; + end if; + + if (mac_tx_valid_i = '1') then + fsm_mac_tx <= wait_channel; + end if; + when wait_channel => + if (phy0_tx_valid_o = '0' and phy1_tx_valid_o = '0' and ifg_good = '1') then + fsm_mac_tx <= wait_send; + mux_phy0 <= connect_mac; + mux_phy1 <= connect_mac; + + end if; + when wait_send => + + if (mac_tx_eof_i = '1' and mac_tx_valid_i = '1' and mac_tx_ready_o = '1') then + + mux_phy0 <= connect_none; + mux_phy1 <= connect_none; + fsm_mac_tx <= wait_ifg; + end if; + when wait_ifg => + mux_phy0 <= connect_none; + mux_phy1 <= connect_none; + if (ifg_good = '1') then + fsm_mac_tx <= idle; + end if; + end case; + end if; + end process; + + + process (clk_i) + begin + if rising_edge(clk_i) then + if (rst_i = '1') then + fsm_mac_rx <= idle; + else + case (fsm_mac_rx) is + when idle=> + mux_mac <= connect_none; + + if (phy0_rx_valid_i = '1') then + fsm_mac_rx <= wait_phy0_rx; + elsif (phy1_rx_valid_i = '1') then + fsm_mac_rx <= wait_phy1_rx; + end if; + + when wait_phy0_rx => + mux_mac <= connect_phy0; + if ( (phy0_rx_valid_i = '0' and phy0_rx_valid_d = '0' and phy0_rx_valid_d2 = '0') and + (phy1_rx_valid_i = '0' and phy1_rx_valid_d = '0' and phy1_rx_valid_d2= '0')) then + fsm_mac_rx <= idle; + end if; + when wait_phy1_rx => + mux_mac <= connect_phy1; + if ( (phy0_rx_valid_i = '0' and phy0_rx_valid_d = '0' and phy0_rx_valid_d2 = '0') and + (phy1_rx_valid_i = '0' and phy1_rx_valid_d = '0' and phy1_rx_valid_d2 = '0')) then + + fsm_mac_rx <= idle; + end if; + + when others => + fsm_mac_rx <= idle; + + end case; + end if; + end if; + end process; + + + + end architecture; + + diff --git a/hdl/ueth_mac.vhd b/hdl/ueth_mac.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a2b06a1ed4cd67ef64ca5915fd8c042a4f1607fa --- /dev/null +++ b/hdl/ueth_mac.vhd @@ -0,0 +1,524 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity ueth_mac is + + + port ( + + + clk_i : in std_logic; + rst_i : in std_logic; + + rst_phy_o : out std_logic; + phy_rxen_o: out std_logic; + phy_txen_o: out std_logic; + + mac_rxd_i : in std_logic_vector (3 downto 0); + mac_txd_o : out std_logic_vector (3 downto 0); + mac_rx_valid_i : in std_logic; + mac_tx_valid_o : out std_logic; + mac_tx_ready_i : in std_logic; + mac_tx_eof_o : out std_logic; + mac_rx_eof_i : in std_logic; + + irq_o : out std_logic; + + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + + master_o : out t_wishbone_master_out; + master_i : in t_wishbone_master_in; + + -- MIIM + phy_mdc_o : out std_logic; + phy_md_i : in std_logic; + phy_md_o : out std_logic; + phy_oe_o : out std_logic + + ); +end entity ueth_mac; + + +architecture rtl of ueth_mac is + +type rx_fsm_states is (idle, preamble_check, wait_sfd, data, eof); +type tx_fsm_states is (idle, preamble, sfd, data, fetch_data, crc_wait, crc, gap); + +signal rx_fsm : rx_fsm_states := idle; +signal tx_fsm : tx_fsm_states := idle; + +signal rx_overflow, rx_done : std_logic; +signal rx_nibble_counter : unsigned (2 downto 0); + +signal tx_underflow, tx_done : std_logic; +signal tx_nibble_counter : unsigned (3 downto 0); +signal rx_ready : std_logic; +signal tx_en, rx_en, tx_pending, rx_pending : std_logic; +signal rst_mac : std_logic; +signal tx_fifo_data_dma, rx_fifo_data_dma : std_logic_vector (35 downto 0); +signal tx_fifo_valid_dma, tx_fifo_ready_dma, rx_fifo_valid_dma, rx_fifo_ready_dma : std_logic; +signal tx_fifo_last_dma : std_logic; +signal rxd_word, txd_word : std_logic_vector (35 downto 0); +signal rxd_word_valid, txd_word_valid, txd_word_ready, rxd_word_ready : std_logic; +signal rxd_word_eof, txd_word_eof : std_logic; +signal rx_fifo_eof_dma : std_logic; +signal mii_rd, mii_done : std_logic; +signal mii_addr : std_logic_vector (4 downto 0); +signal mii_reg : std_logic_vector (15 downto 0); + +signal crc_tx, crc_rx, crc_tx_reversed : std_logic_vector (31 downto 0); +signal rst_crc_rx, rst_crc_tx : std_logic; +signal en_crc_tx : std_logic; + +signal mac_rx_timeout : integer range 0 to 7; + + +attribute syn_encoding : string; +attribute syn_encoding of rx_fsm, tx_fsm : signal is "safe,onehot"; + + + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + +function reverse_vector (a: in std_logic_vector) +return std_logic_vector is + variable result: std_logic_vector(a'RANGE); + alias aa: std_logic_vector(a'REVERSE_RANGE) is a; +begin + for i in aa'RANGE loop + result(i) := aa(i); + end loop; + return result; +end; -- function reverse_any_vector + + +begin + +phy_rxen_o <= rx_en; +phy_txen_o <= tx_en; +rst_phy_o <= rst_mac; + + -- fsm rx + + process (clk_i) + begin + if rising_edge(clk_i) then + if rst_i = '1' or rst_mac = '1' then + rx_fsm <= idle; + rx_done <= '0'; + rx_overflow <= '0'; + rxd_word_valid <= '0'; + mac_rx_timeout <= 0; + else + + + case (rx_fsm) is + when idle => + rx_nibble_counter <= (others => '0'); + if (rxd_word_ready = '1') then + rxd_word_valid <= '0'; + end if; + if (rx_en = '1' and rx_ready = '1' and mac_rx_valid_i = '1' and mac_rxd_i = x"5") then + rx_fsm <= preamble_check; + rx_overflow <= '0'; + rx_done <= '0'; + rxd_word_eof <= '0'; + end if; + when preamble_check => + if (mac_rx_valid_i = '1' and mac_rxd_i /= x"5") then + rx_fsm <= idle; + elsif (mac_rx_valid_i = '1' and mac_rxd_i = x"5") then + rx_nibble_counter <= rx_nibble_counter + 1; + if (rx_nibble_counter = "111") then + rx_fsm <= wait_sfd; + end if; + end if; + when wait_sfd => + if (mac_rx_valid_i = '1' and mac_rxd_i = x"D") then + rx_fsm <= data; + rx_nibble_counter <= (others => '0'); + elsif (mac_rx_valid_i = '1' and mac_rxd_i /= x"D" and mac_rxd_i /= x"5") then + rx_fsm <= idle; + end if; + when data => + rxd_word_valid <= '0'; + if (mac_rx_valid_i = '1' and mac_rx_eof_i = '0') then + rx_nibble_counter <= rx_nibble_counter + 1; + case (to_integer(rx_nibble_counter)) is + + when 7 => rxd_word (31 downto 28) <= mac_rxd_i; + rxd_word (35) <= '1'; + when 6 => rxd_word (27 downto 24) <= mac_rxd_i; + when 5 => rxd_word (23 downto 20) <= mac_rxd_i; + rxd_word (34) <= '1'; + when 4 => rxd_word (19 downto 16) <= mac_rxd_i; + when 3 => rxd_word (15 downto 12) <= mac_rxd_i; + rxd_word (33) <= '1'; + when 2 => rxd_word (11 downto 8) <= mac_rxd_i; + when 1 => rxd_word (7 downto 4) <= mac_rxd_i; + rxd_word (32) <= '1'; + when 0 => rxd_word (3 downto 0) <= mac_rxd_i; + rxd_word (35 downto 32) <= "0000"; + when others => rxd_word <= (others => 'X'); + end case; + + + if (rx_nibble_counter = "111") then + rxd_word_valid <= '1'; + if (rxd_word_ready = '0') then + rx_overflow <= '1'; + end if; + end if; + end if; + if (mac_rx_valid_i = '1' and mac_rx_eof_i = '1') then + rx_fsm <= eof; + if (to_integer(rx_nibble_counter) /= 0 ) then + rxd_word_valid <= '1'; + end if; + end if; + + -- timeout if EOF flag is corrupted + if (mac_rx_valid_i = '1') then + mac_rx_timeout <= 0; + else + mac_rx_timeout <= mac_rx_timeout + 1; + if (mac_rx_timeout > 4) then + rx_fsm <= eof; + end if; + end if; + + when eof => + if (rxd_word_ready = '1') then + rx_done <= '1'; + rx_fsm <= idle; + rxd_word_valid <= '1'; + rxd_word_eof <= '1'; + end if; + + + + when others => + rx_fsm <= idle; + end case; + end if; + end if; + end process; + + + + +-- fsm tx +-- + + +process (clk_i) + begin + if rising_edge(clk_i) then + if rst_i = '1' or rst_mac = '1' then + tx_fsm <= idle; + mac_tx_valid_o <= '0'; + txd_word_ready <= '0'; + mac_tx_eof_o <= '0'; + else + case (tx_fsm) is + when idle => + tx_underflow <= '0'; + mac_txd_o <= x"0"; + if (tx_en = '1' and tx_pending = '1' and txd_word_valid = '1') then + tx_fsm <= preamble; + tx_nibble_counter <= (others => '0'); + + end if; + when preamble => + mac_txd_o <= x"5"; + mac_tx_valid_o <= '1'; + if (mac_tx_valid_o = '1' and mac_tx_ready_i = '1') then + tx_nibble_counter <= tx_nibble_counter + 1; + end if; + if (mac_tx_ready_i = '1' and tx_nibble_counter = 14) then + tx_fsm <= sfd; + mac_txd_o <= x"D"; + end if; + when sfd => + if (mac_tx_ready_i = '1') then + tx_fsm <= data; + mac_tx_valid_o <= '0'; + + end if; + tx_nibble_counter <= (others => '0'); + + when data => + + txd_word_ready <= '0'; + + + if (mac_tx_valid_o = '0' or (mac_tx_ready_i = '1' and mac_tx_valid_o = '1')) then + mac_tx_valid_o <= '1'; + case (to_integer(tx_nibble_counter (2 downto 0))) is + when 0 => mac_txd_o <= txd_word (3 downto 0); + when 1 => mac_txd_o <= txd_word (7 downto 4); + if (txd_word(33) = '0') then + tx_fsm <= crc_wait; + txd_word_ready <= '1'; + end if; + when 2 => mac_txd_o <= txd_word (11 downto 8); + when 3 => mac_txd_o <= txd_word (15 downto 12); + if (txd_word(34) = '0') then + tx_fsm <= crc_wait; + txd_word_ready <= '1'; + end if; + when 4 => mac_txd_o <= txd_word (19 downto 16); + when 5 => mac_txd_o <= txd_word (23 downto 20); + if (txd_word(35) = '0') then + tx_fsm <= crc_wait; + txd_word_ready <= '1'; + end if; + when 6 => mac_txd_o <= txd_word (27 downto 24); + + when 7 => mac_txd_o <= txd_word (31 downto 28); + txd_word_ready <= '1'; + tx_fsm <= fetch_data; + when others => mac_txd_o <= (others => 'X'); + txd_word_ready <= 'X'; + + end case; + end if; + if (mac_tx_valid_o = '0' or (mac_tx_ready_i = '1' and mac_tx_valid_o = '1')) then + + tx_nibble_counter <= tx_nibble_counter + 1; + end if; + + + + when fetch_data => + tx_nibble_counter <= (others => '0'); + if (mac_tx_valid_o = '1' and mac_tx_ready_i = '1') then + mac_tx_valid_o <= '0'; + end if; + + txd_word_ready <= '0'; + if (txd_word_valid = '0') then + if (tx_pending = '1') then + tx_underflow <= '1'; + elsif mac_tx_valid_o = '0' then + tx_fsm <= crc_wait; + + end if; + elsif txd_word_ready = '0' and txd_word_valid = '1' then + -- txd_word_ready <= '0'; + tx_fsm <= data; + --tx_nibble_counter <= (others => '0'); + end if; + when crc_wait => + txd_word_ready <= '0'; + if (mac_tx_ready_i = '1' and mac_tx_valid_o = '1') then + mac_tx_valid_o <= '0'; + end if; + tx_nibble_counter <= (others => '0'); + tx_fsm <= crc; + + when crc => + + if (mac_tx_valid_o = '0' or (mac_tx_ready_i = '1' and mac_tx_valid_o = '1')) then + mac_tx_valid_o <= '1'; + case (to_integer (tx_nibble_counter (2 downto 0))) is + when 0 => mac_txd_o <= crc_tx_reversed (3 downto 0); + when 1 => mac_txd_o <= crc_tx_reversed (7 downto 4); + when 2 => mac_txd_o <= crc_tx_reversed (11 downto 8); + when 3 => mac_txd_o <= crc_tx_reversed (15 downto 12); + when 4 => mac_txd_o <= crc_tx_reversed (19 downto 16); + when 5 => mac_txd_o <= crc_tx_reversed (23 downto 20); + when 6 => mac_txd_o <= crc_tx_reversed (27 downto 24); + when 7 => mac_txd_o <= crc_tx_reversed (31 downto 28); + mac_tx_eof_o <= '1'; + tx_fsm <= gap; + + when others => + mac_txd_o <= (others => 'X'); + end case; + end if; + if (mac_tx_valid_o = '0' or (mac_tx_ready_i = '1' and mac_tx_valid_o = '1')) then + tx_nibble_counter <= tx_nibble_counter + 1; + end if; + when gap => + if (mac_tx_ready_i = '1') then + mac_tx_valid_o <= '0'; + mac_tx_eof_o <= '0'; + tx_nibble_counter <= (others => '0'); + end if; + if (mac_tx_valid_o = '0') then + tx_nibble_counter <= tx_nibble_counter + 1; + if (tx_nibble_counter = x"F") then + tx_fsm <= idle; + end if; + end if; + when others => + tx_fsm <= idle; + mac_tx_valid_o <= '0'; + txd_word_ready <= '0'; + end case; + end if; + end if; +end process; + + crc_tx_reversed <= not reverse_vector (crc_tx); +rst_crc_tx <= '1' when (rst_i = '1' or tx_fsm = idle) else '0'; +en_crc_tx <= mac_tx_valid_o and mac_tx_ready_i when (tx_fsm = data or tx_fsm = fetch_data or tx_fsm = crc_wait) else '0'; +inst_crc_tx : entity work.ueth_crc + port map( + clk_i => clk_i, + rst_i => rst_crc_tx, + + en_i => en_crc_tx, + data_i => mac_txd_o, + crc_o => crc_tx + ); + +rst_crc_rx <= '1' when (rst_i = '1' or rx_fsm /= data) else '0'; + + +inst_crc_rx : entity work.ueth_crc + port map( + clk_i => clk_i, + rst_i => rst_crc_rx, + + en_i => mac_rx_valid_i and not mac_rx_eof_i, + data_i => mac_rxd_i, + crc_o => crc_rx + ); + + +inst_dma : entity work.ueth_dma + + + port map ( + clk_i => clk_i, + rst_i => rst_i, + + rst_mac_o => rst_mac, + rx_en_o => rx_en, + tx_en_o => tx_en, + rx_done_i => rx_done, + tx_done_i => tx_done, + rx_overflow_i => rx_overflow, + tx_underflow_i => tx_underflow, + + tx_pending_o => tx_pending, + + rx_ready_o => rx_ready, + tx_fifo_data_o => tx_fifo_data_dma, + tx_fifo_valid_o => tx_fifo_valid_dma, + tx_fifo_ready_i => tx_fifo_ready_dma, + + + rx_fifo_data_i => rx_fifo_data_dma, + rx_fifo_valid_i => rx_fifo_valid_dma, + rx_fifo_ready_o => rx_fifo_ready_dma, + rx_fifo_eof_i => rx_fifo_eof_dma, + + irq_o => irq_o, + + mii_rd_o => mii_rd, + mii_done_i => mii_done, + mii_reg_i => mii_reg, + mii_addr_o => mii_addr, + + + slave_i => slave_i, + slave_o => slave_o, + + master_o => master_o, + master_i => master_i + + ); + + + fifo_rx : entity work.axis_fifo_cdc + + generic map ( + dwidth => 36, + uwidth => 0, + log2depth => 4, + tcq => 1 ) + port map ( + s_clk => clk_i, + s_reset => rst_i or rst_mac, + + m_clk => clk_i, + m_reset => rst_i or rst_mac, + + s_axis_data => rxd_word, + s_axis_valid => rxd_word_valid, + s_axis_user => (others => '0'), + s_axis_last => rxd_word_eof, + s_axis_ready => rxd_word_ready, + + m_axis_data => rx_fifo_data_dma, + m_axis_valid => rx_fifo_valid_dma, + m_axis_user => open, + m_axis_last => rx_fifo_eof_dma, + m_axis_ready => rx_fifo_ready_dma); + + + fifo_tx : entity work.axis_fifo_cdc + + generic map ( + dwidth => 36, + uwidth => 0, + log2depth => 4, + tcq => 1 ) + port map ( + s_clk => clk_i, + s_reset => rst_i or rst_mac, + + m_clk => clk_i, + m_reset => rst_i or rst_mac, + + s_axis_data => tx_fifo_data_dma, + s_axis_valid => tx_fifo_valid_dma, + s_axis_user => (others => '0'), + s_axis_last => '0', + s_axis_ready => tx_fifo_ready_dma, + + m_axis_data => txd_word, + m_axis_valid => txd_word_valid, + m_axis_user => open, + m_axis_last => open, + m_axis_ready => txd_word_ready); + + +inst_eth_mii : entity work.ueth_miim + + port map ( + clk_i => clk_i, + rst_i => rst_i, + + read_i => mii_rd, + addr_i => mii_addr, + done_o => mii_done, + reg_o => mii_reg, + + phy_mdc_o => phy_mdc_o, + phy_md_i => phy_md_i, + phy_md_o => phy_md_o, + phy_oe_o => phy_oe_o + ); + + +end architecture; + diff --git a/hdl/ueth_miim.vhd b/hdl/ueth_miim.vhd new file mode 100644 index 0000000000000000000000000000000000000000..3cf1c1505a429bfac7688f47ce7df4b940c0058c --- /dev/null +++ b/hdl/ueth_miim.vhd @@ -0,0 +1,194 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity ueth_miim is + + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + read_i : in std_logic; + addr_i : in std_logic_vector (4 downto 0); + done_o : out std_logic; + reg_o : out std_logic_vector (15 downto 0); + + + + --MIIM + phy_mdc_o : out std_logic; + phy_md_i : in std_logic; + phy_md_o : out std_logic; + phy_oe_o : out std_logic + + + + ); +end entity ueth_miim; + + +architecture rtl of ueth_miim is + + constant c_PHY_ADDR : std_logic_vector (4 downto 0) := "00000"; + signal reg_phy_addr : std_logic_vector (4 downto 0) := c_PHY_ADDR; + signal clk_en : std_logic; + signal clk_divider : unsigned (3 downto 0); + signal counter : unsigned (4 downto 0); + signal clk_miim : std_logic; + type t_fsm is (idle, preamble, start_0, start_1, opcode_read_0, opcode_read_1, phy_addr, addr, tristate, skip, read_reg); + signal reg_addr : std_logic_vector (4 downto 0); + signal fsm : t_fsm := idle; + signal reg_phy : std_logic_vector (15 downto 0); + + attribute syn_encoding : string; +attribute syn_encoding of fsm : signal is "safe,onehot"; + + attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; +begin + +phy_mdc_o <= clk_miim; + + process (clk_i) + begin + if rising_edge(clk_i) then + if rst_i = '1' then + clk_divider <= (others => '0'); + clk_miim <= '1'; + clk_en <= '0'; + else + clk_en <= '0'; + clk_divider <= clk_divider+1; + if (clk_divider = 0) then + --clk_divider <= (others => '0'); + clk_en <= '1'; + clk_miim <= not clk_miim; + end if; + end if; + end if; + end process; + + + process (clk_i) + begin + if rising_edge (clk_i) then + if rst_i = '1' then + fsm <= idle; + done_o <= '0'; + phy_oe_o <= '0'; + reg_phy <= (others => '0'); + else + case (fsm) is + when idle => + phy_md_o <= '1'; + + phy_oe_o <= '0'; + if (read_i = '1') then + fsm <= preamble; + counter <= (others => '0'); + reg_addr <= addr_i; + done_o <= '0'; + end if; + when preamble => + if (clk_en = '1' and clk_miim = '0') then + phy_md_o <= '1'; + phy_oe_o <= '1'; + counter <= counter+1; + if (counter = 31) then + fsm <= start_0; + counter <= (others => '0'); + end if; + end if; + when start_0 => + if (clk_en = '1' and clk_miim = '0') then + phy_md_o <= '0'; + phy_oe_o <= '1'; + fsm <= start_1; + end if; + + when start_1 => + if (clk_en = '1' and clk_miim = '0') then + phy_md_o <= '1'; + fsm <= opcode_read_0; + end if; + + when opcode_read_0 => + if (clk_en = '1' and clk_miim = '0') then + phy_md_o <= '1'; + fsm <= opcode_read_1; + end if; + + when opcode_read_1 => + if (clk_en = '1' and clk_miim = '0') then + phy_md_o <= '0'; + fsm <= phy_addr; + reg_phy_addr <= c_PHY_ADDR; + counter <= (others => '0'); + end if; + + when phy_addr => + if (clk_en = '1' and clk_miim = '0') then + phy_md_o <= reg_phy_addr (4); + reg_phy_addr <= reg_phy_addr (3 downto 0) & "0"; + counter <= counter + 1; + end if; + if (counter = 5) then + fsm <= addr; + counter <= (others => '0'); + end if; + + when addr => + if (clk_en = '1' and clk_miim = '0') then + phy_md_o <= reg_addr (4); + reg_addr <= reg_addr (3 downto 0) & "0"; + counter <= counter + 1; + end if; + if (counter = 5) then + fsm <= tristate; + counter <= (others => '0'); + end if; + + when tristate => + if (clk_en = '1' and clk_miim = '0') then + phy_oe_o <= '0'; + fsm <= skip; + end if; + + when skip => + if (clk_en = '1' and clk_miim = '0') then + fsm <= read_reg; + end if; + + when read_reg => + if (clk_en = '1' and clk_miim = '0') then + reg_phy <= reg_phy (14 downto 0) & phy_md_i; + counter <= counter + 1; + if (counter = 15) then + fsm <= idle; + counter <= (others => '0'); + done_o <= '1'; + end if; + end if; + + when others => + fsm <= idle; + + end case; + end if; + end if; + end process; + + reg_o <= reg_phy; + end architecture; diff --git a/hdl/ueth_phy.vhd b/hdl/ueth_phy.vhd new file mode 100644 index 0000000000000000000000000000000000000000..2c986358ccd2594f9fbdf63b4d0fe8305d645d08 --- /dev/null +++ b/hdl/ueth_phy.vhd @@ -0,0 +1,475 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity ueth_phy is + + + port ( + + --TX + phy_tx_clk_i : in std_logic; + rst_tx_i : in std_logic; + phy_txd_o : out std_logic_vector (3 downto 0); + phy_txen_o : out std_logic; + phy_txerr_o : out std_logic; + + --RX + phy_rx_clk_i : in std_logic; + rst_rx_i : in std_logic; + phy_rxd_i : in std_logic_vector (3 downto 0); + phy_rxdv_i : in std_logic; + phy_rxerr_i : in std_logic; + col_i : in std_logic; + crs_i : in std_logic; + + tx_pending_i : in std_logic; + rx_pending_i : in std_logic; + + tx_done_o : out std_logic; + rx_done_o : out std_logic; + rx_err_o : out std_logic; + + + tx_fifo_data_i : in std_logic_vector (35 downto 0); + tx_fifo_valid_i : in std_logic; + tx_fifo_ready_o : out std_logic; + tx_fifo_underflow_o : out std_logic; + tx_fifo_empty_i : in std_logic; + tx_byte_sel_i : in std_logic_vector (3 downto 0); + + rx_fifo_data_o : out std_logic_vector (35 downto 0); + rx_fifo_valid_o : out std_logic; + rx_fifo_ready_i : in std_logic; + rx_fifo_overflow_o : out std_logic; + rx_fifo_empty_i : in std_logic; + rx_byte_sel_o : out std_logic_vector (3 downto 0) + + + ); +end entity ueth_phy; + + +architecture rtl of ueth_phy is + +type t_tx_fsm is (idle, preamble, sfd, data, crc, gap, wait_ack); +type t_rx_fsm is (idle, wait_preamble, wait_sfd, data, wait_ack); + +signal tx_fsm : t_tx_fsm := idle; +signal rx_fsm : t_rx_fsm := idle; + +signal preamble_counter, gap_counter : unsigned (3 downto 0); +signal tx_nibble_counter, rx_nibble_counter : unsigned (2 downto 0); + +signal rx_data, crc_tx, crc_rx : std_logic_vector (31 downto 0); +signal rst_tx, rst_rx, rx_done, rx_done_d : std_logic; + +signal tx_data : std_logic_vector (35 downto 0); + +signal enable_crc_tx : std_logic; +signal phy_txd_n,phy_rxd_n : std_logic_vector (3 downto 0); + +function reverse_vector (a: in std_logic_vector) +return std_logic_vector is + variable result: std_logic_vector(a'RANGE); + alias aa: std_logic_vector(a'REVERSE_RANGE) is a; +begin + for i in aa'RANGE loop + result(i) := aa(i); + end loop; + return result; +end; -- function reverse_any_vector + +function f_word2nibble (data : std_logic_vector (31 downto 0); nibble : unsigned (2 downto 0)) return std_logic_vector is + variable data_rev : std_logic_vector (31 downto 0); +begin + data_rev := not reverse_vector (data); + +case (to_integer(nibble)) is + when 7 => return (data_rev(31 downto 28)); + when 6 => return (data_rev(27 downto 24)); + when 5 => return (data_rev(23 downto 20)); + when 4 => return (data_rev(19 downto 16)); + when 3 => return (data_rev(15 downto 12)); + when 2 => return (data_rev(11 downto 8)); + when 1 => return (data_rev(7 downto 4)); + when 0 => return (data_rev(3 downto 0)); +when others => return "XXXX"; +end case; +end f_word2nibble; + + + +function f_byte_sel (byte_counter : unsigned (1 downto 0)) return std_logic_vector is +begin + case (to_integer (byte_counter)) is + when 0 => return "1111"; + when 1 => return "0001"; + when 2 => return "0011"; + when 3 => return "0111"; + when others => return "XXXX"; + end case; +end f_byte_sel; + + + function f_byte_count (byte_sel : std_logic_vector (3 downto 0)) return integer is + begin + case (byte_sel) is + when "0001" => return 1; + when "0011" => return 2; + when "0111" => return 3; + when "1111" => return 4; + when others => return -1; + end case; + end f_byte_count; + + + attribute syn_encoding : string; +attribute syn_encoding of tx_fsm, rx_fsm : signal is "safe,onehot"; + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + +begin + + + + + process (phy_tx_clk_i, rst_tx) + begin + if (rst_tx_i = '1') then + + + tx_fsm <= idle; + tx_done_o <= '0'; + tx_fifo_ready_o <= '0'; + tx_fifo_underflow_o <= '0'; + phy_txen_o <= '0'; + elsif rising_edge(phy_tx_clk_i) then + + case (tx_fsm) is + when idle => + tx_done_o <= '0'; + phy_txd_o <= (others => '0'); + phy_txerr_o <= '0'; + phy_txen_o <= '0'; + enable_crc_tx <= '0'; + preamble_counter <= (others => '0'); + tx_nibble_counter <= (others => '0'); + gap_counter <= (others => '0'); + + if (tx_fifo_valid_i = '1' and tx_pending_i = '1') then + tx_fsm <= preamble; + tx_fifo_underflow_o <= '0'; + end if; + when preamble => + phy_txd_o <= x"5"; + phy_txen_o <= '1'; + preamble_counter <= preamble_counter + 1; + if (preamble_counter = 15) then + tx_fsm <= sfd; + end if; + when sfd => + phy_txd_o <= x"D"; + tx_fsm <= data; + tx_data <= tx_fifo_data_i; + tx_fifo_ready_o <= '1'; + enable_crc_tx <= '1'; + when data => + + tx_fifo_ready_o <= '0'; + phy_txd_o <= tx_data (3 downto 0); + tx_data (31 downto 0) <= "0000" & tx_data (31 downto 4); + tx_nibble_counter <= tx_nibble_counter + 1; + if (tx_data (35 downto 32) /= "1111" and tx_nibble_counter = 2*f_byte_count (tx_fifo_data_i (35 downto 32))-1) then + tx_fsm <= crc; + enable_crc_tx <= '0'; + tx_nibble_counter <= (others => '0'); + end if; + if (tx_fifo_valid_i = '0' and tx_nibble_counter = 7 ) then + if ( tx_pending_i = '1') then + tx_fifo_underflow_o <= '1'; + phy_txerr_o <= '1'; + phy_txd_o <= (others => '1'); + else + + tx_fsm <= crc; + enable_crc_tx <= '0'; + tx_nibble_counter <= (others => '0'); + end if; + end if; + if (tx_nibble_counter = 7 and tx_fifo_valid_i = '1') then + tx_data <= tx_fifo_data_i; + tx_fifo_ready_o <= '1'; + end if; + +-- case (to_integer(tx_nibble_counter)) is +-- when 7 => phy_txd_o <= tx_fifo_data_i (31 downto 28); +-- when 6 => phy_txd_o <= tx_fifo_data_i (27 downto 24); +-- when 5 => phy_txd_o <= tx_fifo_data_i (23 downto 20); +-- when 4 => phy_txd_o <= tx_fifo_data_i (19 downto 16); +-- when 3 => phy_txd_o <= tx_fifo_data_i (15 downto 12); +-- when 2 => phy_txd_o <= tx_fifo_data_i (11 downto 8); +-- when 1 => phy_txd_o <= tx_fifo_data_i (7 downto 4); +-- when 0 => phy_txd_o <= tx_fifo_data_i (3 downto 0); +-- when others => phy_txd_o <= (others => 'X'); +-- end case; + -- if (tx_nibble_counter = 6 and tx_fifo_empty_i = '0') then +-- tx_fifo_ready_o <= '1'; +-- end if; +-- if(tx_fifo_data_i (35 downto 32) /= "1111" and tx_nibble_counter = 2*f_byte_count (tx_fifo_data_i (35 downto 32))-1) then +-- tx_fifo_ready_o <= '1'; +-- tx_fsm <= crc; +-- tx_nibble_counter <= (others => '0'); +-- end if; +-- if (tx_fifo_empty_i = '1' and tx_fifo_ready_o = '0' and tx_nibble_counter = 7) then +-- +-- if (tx_pending_i = '1') then +-- --to do error +-- tx_fifo_underflow_o <= '1'; +-- phy_txerr_o <= '1'; +-- phy_txd_o <= (others => '1'); +-- +-- else +-- tx_fifo_ready_o <= '1'; +-- tx_fsm <= crc; +-- tx_nibble_counter <= (others => '0'); +-- end if; +-- end if; + + when crc => + enable_crc_tx <= '0'; + tx_fifo_ready_o <= '0'; + + + phy_txerr_o <= '0'; + phy_txd_o <= f_word2nibble(crc_tx, tx_nibble_counter); + tx_nibble_counter <= tx_nibble_counter + 1; + if (tx_nibble_counter = 7) then + tx_fsm <= gap; + end if; + when gap => + phy_txen_o <= '0'; + phy_txd_o <= (others => '0'); + gap_counter <= gap_counter + 1; + if (gap_counter = 11) then + tx_fsm <= idle; + tx_done_o <= '1'; + end if; + when wait_ack => + + + when others => + tx_fsm <= idle; + end case; + end if; + --end if; + end process; + + +phy_txd_n <= tx_data (3 downto 0); + + process (phy_tx_clk_i) + begin + if rising_edge (phy_tx_clk_i) then + if (tx_fsm = preamble) then + crc_tx <= (others => '1'); + elsif (enable_crc_tx = '1') then + crc_tx(0) <= crc_tx(28) xor phy_txd_n(3); + crc_tx(1) <= crc_tx(28) xor crc_tx(29) xor phy_txd_n(2) xor phy_txd_n(3); + crc_tx(2) <= crc_tx(28) xor crc_tx(29) xor crc_tx(30) xor phy_txd_n(1) xor phy_txd_n(2) xor phy_txd_n(3); + crc_tx(3) <= crc_tx(29) xor crc_tx(30) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(1) xor phy_txd_n(2); + crc_tx(4) <= crc_tx(0) xor crc_tx(28) xor crc_tx(30) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(1) xor phy_txd_n(3); + crc_tx(5) <= crc_tx(1) xor crc_tx(28) xor crc_tx(29) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(2) xor phy_txd_n(3); + crc_tx(6) <= crc_tx(2) xor crc_tx(29) xor crc_tx(30) xor phy_txd_n(1) xor phy_txd_n(2); + crc_tx(7) <= crc_tx(3) xor crc_tx(28) xor crc_tx(30) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(1) xor phy_txd_n(3); + crc_tx(8) <= crc_tx(4) xor crc_tx(28) xor crc_tx(29) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(2) xor phy_txd_n(3); + crc_tx(9) <= crc_tx(5) xor crc_tx(29) xor crc_tx(30) xor phy_txd_n(1) xor phy_txd_n(2); + crc_tx(10) <= crc_tx(6) xor crc_tx(28) xor crc_tx(30) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(1) xor phy_txd_n(3); + crc_tx(11) <= crc_tx(7) xor crc_tx(28) xor crc_tx(29) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(2) xor phy_txd_n(3); + crc_tx(12) <= crc_tx(8) xor crc_tx(28) xor crc_tx(29) xor crc_tx(30) xor phy_txd_n(1) xor phy_txd_n(2) xor phy_txd_n(3); + crc_tx(13) <= crc_tx(9) xor crc_tx(29) xor crc_tx(30) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(1) xor phy_txd_n(2); + crc_tx(14) <= crc_tx(10) xor crc_tx(30) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(1); + crc_tx(15) <= crc_tx(11) xor crc_tx(31) xor phy_txd_n(0); + crc_tx(16) <= crc_tx(12) xor crc_tx(28) xor phy_txd_n(3); + crc_tx(17) <= crc_tx(13) xor crc_tx(29) xor phy_txd_n(2); + crc_tx(18) <= crc_tx(14) xor crc_tx(30) xor phy_txd_n(1); + crc_tx(19) <= crc_tx(15) xor crc_tx(31) xor phy_txd_n(0); + crc_tx(20) <= crc_tx(16); + crc_tx(21) <= crc_tx(17); + crc_tx(22) <= crc_tx(18) xor crc_tx(28) xor phy_txd_n(3); + crc_tx(23) <= crc_tx(19) xor crc_tx(28) xor crc_tx(29) xor phy_txd_n(2) xor phy_txd_n(3); + crc_tx(24) <= crc_tx(20) xor crc_tx(29) xor crc_tx(30) xor phy_txd_n(1) xor phy_txd_n(2); + crc_tx(25) <= crc_tx(21) xor crc_tx(30) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(1); + crc_tx(26) <= crc_tx(22) xor crc_tx(28) xor crc_tx(31) xor phy_txd_n(0) xor phy_txd_n(3); + crc_tx(27) <= crc_tx(23) xor crc_tx(29) xor phy_txd_n(2); + crc_tx(28) <= crc_tx(24) xor crc_tx(30) xor phy_txd_n(1); + crc_tx(29) <= crc_tx(25) xor crc_tx(31) xor phy_txd_n(0); + crc_tx(30) <= crc_tx(26); + crc_tx(31) <= crc_tx(27); + + end if; + end if; + end process; + + process (phy_rx_clk_i, rst_rx) + begin +if (rst_rx_i = '1') then + + + rx_fsm <= idle; + + rx_done_o <= '0'; + rx_fifo_valid_o <= '0'; + rx_err_o <= '0'; + rx_fifo_overflow_o <= '0'; + elsif rising_edge(phy_rx_clk_i) then + + case (rx_fsm) is + when idle => + rx_done_o <= '0'; + rx_err_o <= '0'; + rx_data <= (others => '0'); + rx_fifo_valid_o <= '0'; + rx_nibble_counter <= (others => '0'); + rx_byte_sel_o <= (others => '0'); + if (rx_pending_i = '1') then + rx_done_o <= '0'; + rx_err_o <= '0'; + rx_fifo_overflow_o <= '0'; + rx_fsm <= wait_preamble; + end if; + when wait_preamble => + if (phy_rxdv_i = '1' and phy_rxd_i = x"5") then + rx_fsm <= wait_sfd; + + end if; + when wait_sfd => + if (phy_rxd_i = x"D") then + rx_fsm <= data; + end if; + + when data => + rx_fifo_valid_o <= '0'; + if (phy_rxdv_i = '1' ) then + -- rx_data <= rx_data (27 downto 0) & phy_rxd_i; + rx_nibble_counter <= rx_nibble_counter + 1; + case (to_integer(rx_nibble_counter)) is + when 7 => rx_fifo_data_o (31 downto 28) <= phy_rxd_i; + when 6 => rx_fifo_data_o (27 downto 24) <= phy_rxd_i; + when 5 => rx_fifo_data_o (23 downto 20) <= phy_rxd_i; + when 4 => rx_fifo_data_o (19 downto 16) <= phy_rxd_i; + when 3 => rx_fifo_data_o (15 downto 12) <= phy_rxd_i; + when 2 => rx_fifo_data_o (11 downto 8) <= phy_rxd_i; + when 1 => rx_fifo_data_o (7 downto 4) <= phy_rxd_i; + when 0 => rx_fifo_data_o (3 downto 0) <= phy_rxd_i; + when others => rx_fifo_data_o <= (others => 'X'); + end case; + + end if; + if ( (rx_nibble_counter = 7)) then + rx_fifo_valid_o <= '1'; + rx_fifo_data_o (35 downto 32) <= "1111"; + end if; + + if (phy_rxdv_i = '0' and rx_nibble_counter /= 0) then + rx_fifo_data_o (35 downto 32) <= f_byte_sel(rx_nibble_counter (2 downto 1)); + rx_fifo_valid_o <= '1'; + end if; + if (phy_rxdv_i = '0' ) then + + rx_fsm <= wait_ack; + rx_nibble_counter <= (others => '0'); + end if; + + if (rx_fifo_ready_i = '0') then + rx_fifo_overflow_o <= '1'; + end if; + + if (phy_rxdv_i = '1' and phy_rxerr_i = '1') then + rx_err_o <= '1'; + end if; + + when wait_ack => + rx_fifo_valid_o <= '0'; + if (rx_fifo_empty_i = '1') then + rx_done_o <= '1'; + end if; + if (rx_pending_i = '0') then + rx_fsm <= idle; + end if; + + when others => + rx_fsm <= idle; + end case; + + if (phy_rxdv_i = '1' and phy_rxerr_i = '1') then + rx_err_o <= '1'; + end if; + end if; + --end if; + end process; + + +phy_rxd_n <= phy_rxd_i; + process (phy_rx_clk_i,crc_rx, phy_rxd_n) + begin + if rising_edge (phy_rx_clk_i) then + if (rx_fsm = wait_sfd) then + crc_rx <= (others => '1'); + elsif (rx_fsm = data and phy_rxdv_i = '1') then + crc_rx(0) <= crc_rx(28) xor phy_rxd_n(3); + crc_rx(1) <= crc_rx(28) xor crc_rx(29) xor phy_rxd_n(2) xor phy_rxd_n(3); + crc_rx(2) <= crc_rx(28) xor crc_rx(29) xor crc_rx(30) xor phy_rxd_n(1) xor phy_rxd_n(2) xor phy_rxd_n(3); + crc_rx(3) <= crc_rx(29) xor crc_rx(30) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(1) xor phy_rxd_n(2); + crc_rx(4) <= crc_rx(0) xor crc_rx(28) xor crc_rx(30) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(1) xor phy_rxd_n(3); + crc_rx(5) <= crc_rx(1) xor crc_rx(28) xor crc_rx(29) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(2) xor phy_rxd_n(3); + crc_rx(6) <= crc_rx(2) xor crc_rx(29) xor crc_rx(30) xor phy_rxd_n(1) xor phy_rxd_n(2); + crc_rx(7) <= crc_rx(3) xor crc_rx(28) xor crc_rx(30) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(1) xor phy_rxd_n(3); + crc_rx(8) <= crc_rx(4) xor crc_rx(28) xor crc_rx(29) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(2) xor phy_rxd_n(3); + crc_rx(9) <= crc_rx(5) xor crc_rx(29) xor crc_rx(30) xor phy_rxd_n(1) xor phy_rxd_n(2); + crc_rx(10) <= crc_rx(6) xor crc_rx(28) xor crc_rx(30) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(1) xor phy_rxd_n(3); + crc_rx(11) <= crc_rx(7) xor crc_rx(28) xor crc_rx(29) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(2) xor phy_rxd_n(3); + crc_rx(12) <= crc_rx(8) xor crc_rx(28) xor crc_rx(29) xor crc_rx(30) xor phy_rxd_n(1) xor phy_rxd_n(2) xor phy_rxd_n(3); + crc_rx(13) <= crc_rx(9) xor crc_rx(29) xor crc_rx(30) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(1) xor phy_rxd_n(2); + crc_rx(14) <= crc_rx(10) xor crc_rx(30) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(1); + crc_rx(15) <= crc_rx(11) xor crc_rx(31) xor phy_rxd_n(0); + crc_rx(16) <= crc_rx(12) xor crc_rx(28) xor phy_rxd_n(3); + crc_rx(17) <= crc_rx(13) xor crc_rx(29) xor phy_rxd_n(2); + crc_rx(18) <= crc_rx(14) xor crc_rx(30) xor phy_rxd_n(1); + crc_rx(19) <= crc_rx(15) xor crc_rx(31) xor phy_rxd_n(0); + crc_rx(20) <= crc_rx(16); + crc_rx(21) <= crc_rx(17); + crc_rx(22) <= crc_rx(18) xor crc_rx(28) xor phy_rxd_n(3); + crc_rx(23) <= crc_rx(19) xor crc_rx(28) xor crc_rx(29) xor phy_rxd_n(2) xor phy_rxd_n(3); + crc_rx(24) <= crc_rx(20) xor crc_rx(29) xor crc_rx(30) xor phy_rxd_n(1) xor phy_rxd_n(2); + crc_rx(25) <= crc_rx(21) xor crc_rx(30) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(1); + crc_rx(26) <= crc_rx(22) xor crc_rx(28) xor crc_rx(31) xor phy_rxd_n(0) xor phy_rxd_n(3); + crc_rx(27) <= crc_rx(23) xor crc_rx(29) xor phy_rxd_n(2); + crc_rx(28) <= crc_rx(24) xor crc_rx(30) xor phy_rxd_n(1); + crc_rx(29) <= crc_rx(25) xor crc_rx(31) xor phy_rxd_n(0); + crc_rx(30) <= crc_rx(26); + crc_rx(31) <= crc_rx(27); + + + + end if; + end if; + end process; + + + +end architecture; + diff --git a/hdl/ueth_uphy.vhd b/hdl/ueth_uphy.vhd new file mode 100644 index 0000000000000000000000000000000000000000..d6b3370b43c73a6987bbfe1e1ec95b280d662ac1 --- /dev/null +++ b/hdl/ueth_uphy.vhd @@ -0,0 +1,206 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity ueth_uphy is + + + port ( + + clk_i : in std_logic; + rst_i : in std_logic; + + rx_en_i : in std_logic; + + + rxd_o : out std_logic_vector (3 downto 0); + rxdv_o : out std_logic; + rx_ready_i : in std_logic; + rx_eof_o : out std_logic; + + txd_i : in std_logic_vector (3 downto 0); + txdv_i : in std_logic; + tx_ready_o : out std_logic; + + + --PHY TX + phy_tx_clk_i : in std_logic; + + phy_txd_o : out std_logic_vector (3 downto 0); + phy_txen_o : out std_logic; + + + + --PHY RX + phy_rx_clk_i : in std_logic; + + phy_rxd_i : in std_logic_vector (3 downto 0); + phy_rxdv_i : in std_logic; + phy_rxerr_i : in std_logic + + ); +end entity ueth_uphy; + +architecture rtl of ueth_uphy is +signal rst_tx, rst_tx_d, rst_rx, rst_rx_d : std_logic; +signal fifo_rxd, fifo_txd : std_logic_vector (3 downto 0); +signal fifo_rxdv, fifo_txdv, fifo_txdv_d : std_logic; +signal fifo_tx_ready : std_logic; +signal rx_en, rx_en_d, rx_en_f, rx_abort, rx_on : std_logic; +signal rx_activity : std_logic; +signal phy_rxdv_d, fifo_eof : std_logic; + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + +begin + + -- PHY's clocks are not running during resets, therefore we use async reset logic + process (phy_rx_clk_i, rst_i) + begin + if rst_i = '1' then + rst_rx <= '1'; + rst_rx_d <= '1'; + rx_en_f <= '0'; + rx_en <= '0'; + elsif rising_edge(phy_rx_clk_i) then + rst_rx_d <= '0'; + rst_rx <= rst_rx_d; + rx_en_f <= rx_en_i; + rx_en <= rx_en_f; + end if; + end process; + + + process (phy_tx_clk_i, rst_i) + begin + if rst_i = '1' then + rst_tx <= '1'; + rst_tx_d <= '1'; + elsif rising_edge(phy_tx_clk_i) then + rst_tx_d <= '0'; + rst_tx <= rst_tx_d; + end if; + end process; + + process (phy_tx_clk_i, rst_rx) + begin + if rst_tx = '1' then + fifo_txdv_d <= '0'; + elsif rising_edge(phy_tx_clk_i) then + fifo_txdv_d <= fifo_txdv; + + end if; +end process; + + + + + + phy_txd_o <= fifo_txd; + phy_txen_o <= fifo_txdv and fifo_txdv_d; + fifo_tx_ready <= fifo_txdv_d; -- one nibble margin to compensate + -- frequency difference + + + + + + + fifo_rxd <= phy_rxd_i; + fifo_rxdv <= (phy_rxdv_i or (phy_rxdv_d and not phy_rxdv_i)) and rx_on; + fifo_eof <= phy_rxdv_d and not phy_rxdv_i; + + + + rx_on <= rx_en and not rx_abort; + + + + -- rx_en is active only after rst_i is de-asserted (MAC force rx_en_i to 0 after reset) + process (phy_rx_clk_i) + begin + if rising_edge (phy_rx_clk_i) then + phy_rxdv_d <= phy_rxdv_i; + if (rst_rx = '1') then + rx_en_d <= '0'; + rx_abort <= '0'; + else + rx_en_d <= rx_en; + if (rx_en = '1' and rx_en_d = '0' and phy_rxdv_i = '1') then + rx_abort <= '1'; + end if; + if (phy_rxdv_i = '0') then + rx_abort <= '0'; + end if; + end if; + end if; + end process; + + fifo_rx : entity work.axis_fifo_cdc + + generic map ( + dwidth => 4, + uwidth => 0, + log2depth => 4, + tcq => 1 ) + port map ( + s_clk => phy_rx_clk_i, + s_reset => rst_rx or rx_abort, + + m_clk => clk_i, + m_reset => rst_i or not rx_en_i, + + s_axis_data => fifo_rxd, + s_axis_valid => fifo_rxdv, + s_axis_user => (others => '0'), + s_axis_last => fifo_eof, + s_axis_ready => open, + + m_axis_data => rxd_o, + m_axis_valid => rxdv_o, + m_axis_user => open, + m_axis_last => rx_eof_o, + m_axis_ready => rx_ready_i); + + + fifo_tx : entity work.axis_fifo_cdc + + generic map ( + dwidth => 4, + uwidth => 0, + log2depth => 4, + tcq => 1 ) + port map ( + s_clk => clk_i, + s_reset => rst_i, -- or not tx_en_i, + + m_clk => phy_tx_clk_i, + m_reset => rst_tx, + + s_axis_data => txd_i, + s_axis_valid => txdv_i, + s_axis_user => (others => '0'), + s_axis_last => '0', + s_axis_ready => tx_ready_o, + + m_axis_data => fifo_txd, + m_axis_valid => fifo_txdv, + m_axis_user => open, + m_axis_last => open, + m_axis_ready => fifo_tx_ready); + + end architecture; + diff --git a/hdl/ueth_wb.vhd b/hdl/ueth_wb.vhd new file mode 100644 index 0000000000000000000000000000000000000000..3011639fcb27ef82bbb1720381c78e40dd7f719f --- /dev/null +++ b/hdl/ueth_wb.vhd @@ -0,0 +1,471 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity ueth_wb is + + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + + rx_done_i : in std_logic; + tx_done_i : in std_logic; + rx_overflow_i : in std_logic; + tx_underflow_i : in std_logic; + + tx_pending_o : out std_logic; + rx_pending_o : out std_logic; + + tx_fifo_data_o : out std_logic_vector (35 downto 0); + tx_fifo_valid_o : out std_logic; + tx_fifo_ready_i : in std_logic; + tx_byte_sel_o : out std_logic_vector (3 downto 0); + + rx_fifo_data_i : in std_logic_vector (35 downto 0); + rx_fifo_valid_i : in std_logic; + rx_fifo_ready_o : out std_logic; + rx_byte_sel_i : in std_logic_vector (3 downto 0); + + irq_o : out std_logic; + + mii_rd_o : out std_logic; + mii_done_i : in std_logic; + mii_addr_o : out std_logic_vector (4 downto 0); + mii_reg_i : in std_logic_vector (15 downto 0); + + mii_monitor_o : out std_logic; + rst_mac_o : out std_logic; + rst_phy_o : out std_logic; + rst_phy_i : in std_logic; + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + + master_o : out t_wishbone_master_out; + master_i : in t_wishbone_master_in + + ); +end entity ueth_wb; + + +architecture rtl of ueth_wb is + + type r_descriptor is record + int_flag : std_logic; + size : unsigned (10 downto 0); + addr : std_logic_vector (15 downto 0); + busy : std_logic; + fifo_flow_error : std_logic; + end record r_descriptor; + + function f_byte_count (byte_sel : std_logic_vector (3 downto 0)) return integer is + begin + case (byte_sel) is + when "0001" => return 1; + when "0011" => return 2; + when "0111" => return 3; + when "1111" => return 4; + when others => return 0; + end case; + end f_byte_count; + + function f_byte_sel (byte_counter : unsigned (1 downto 0)) return std_logic_vector is + begin + case (to_integer (byte_counter)) is + when 0 => return "1111"; + when 1 => return "0001"; + when 2 => return "0011"; + when 3 => return "0111"; + when others => return "XXXX"; + end case; + end f_byte_sel; + + + constant c_ETHERTYPE_POWERLINK : std_logic_vector (15 downto 0) := x"ab88"; + constant rx_descriptor0_addr : std_logic_vector (15 downto 0) := x"7400"; + constant rx_descriptor1_addr : std_logic_vector (15 downto 0) := x"79ec"; + + type t_fsm_rx is (idle, setup, read_word, write_word); + type t_fsm_tx is (idle, read_word, write_word, write_partial_word, wait_tx_done); + type t_fsm_dma is (idle, transfer); + + signal fsm_rx : t_fsm_rx := idle; + signal fsm_tx : t_fsm_tx := idle; + signal fsm_dma : t_fsm_dma := idle; + + signal rx_descriptor0, rx_descriptor1, tx_descriptor : r_descriptor; + signal tx_enable, rx_enable, mii_scrubber_enable : std_logic; + signal peding_tx, pending_rx : std_logic; + signal dma_write, dma_read : std_logic; + signal read_addr, write_addr : unsigned (15 downto 0); + signal dma_write_bsel : std_logic_vector (3 downto 0); + signal tx_pkt_sent_p, rx_pkt_recv_p : std_logic; + signal tx_bytes, rx_bytes : unsigned (10 downto 0); + signal dma_read_req, dma_read_done, dma_write_req, dma_write_done : std_logic; + signal data_tx, data_rx : std_logic_vector (31 downto 0); + signal rx_desc_taken : std_logic; + signal rx_ethertype : std_logic_vector(15 downto 0); + +signal mii_read_p, mii_done : std_logic; +signal mii_reg : std_logic_vector (15 downto 0); + +signal phy_reset, rst_phy_d : std_logic; + + +attribute syn_encoding : string; +attribute syn_encoding of fsm_rx, fsm_tx, fsm_dma : signal is "safe,onehot"; + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; +begin + + irq_o <= rx_descriptor0.int_flag or rx_descriptor1.int_flag or tx_descriptor.int_flag or phy_reset; + + rx_descriptor0.addr <= rx_descriptor0_addr; + rx_descriptor1.addr <= rx_descriptor1_addr; + + tx_descriptor.fifo_flow_error <= tx_underflow_i; + + slave_o.stall <= (not slave_o.ack) and slave_i.cyc and slave_i.stb; + + process (clk_i) + begin + + if rising_edge (clk_i) then + if (rst_i) then + tx_enable <= '0'; + rx_enable <= '0'; + rx_descriptor0.busy <= '0'; + rx_descriptor1.busy <= '0'; + tx_descriptor.busy <= '0'; + rx_descriptor0.int_flag <= '0'; + rx_descriptor1.int_flag <= '0'; + tx_descriptor.int_flag <= '0'; + mii_monitor_o <= '0'; + rst_mac_o <= '1'; + rst_phy_o <= '1'; + phy_reset <= '0'; + else + slave_o.ack <= '0'; + mii_read_p <= '0'; + if (slave_i.stb = '1' and slave_i.cyc = '1' and slave_o.ack = '0') then + slave_o.ack <= '1'; + if (slave_i.adr(4 downto 2) = "000") then + slave_o.dat (31) <= rx_descriptor0.busy; + slave_o.dat (30) <= rx_descriptor0.fifo_flow_error; + slave_o.dat (29) <= rx_descriptor0.int_flag; + slave_o.dat (26 downto 16) <= std_logic_vector(rx_descriptor0.size); + slave_o.dat (15 downto 0) <= (rx_descriptor0.addr); + rx_descriptor0.int_flag <= '0'; + if (slave_i.we = '1') then + -- rx_descriptor0.int_flag <= slave_o.dat (29); + if (rx_descriptor0.busy = '0') then + rx_descriptor0.busy <= slave_i.dat(31); + --rx_descriptor.size <= unsigned(slave_i.dat (10 downto 0)); + end if; + end if; + elsif (slave_i.adr(4 downto 2) = "001") then + slave_o.dat (31) <= rx_descriptor1.busy; + slave_o.dat (30) <= rx_descriptor1.fifo_flow_error; + slave_o.dat (29) <= rx_descriptor1.int_flag; + slave_o.dat (26 downto 16) <= std_logic_vector(rx_descriptor1.size); + slave_o.dat (15 downto 0) <= (rx_descriptor1.addr); + rx_descriptor1.int_flag <= '0'; + if (slave_i.we = '1') then + -- rx_descriptor1.int_flag <= slave_o.dat (29); + if (rx_descriptor1.busy = '0') then + rx_descriptor1.busy <= slave_i.dat(31); + --rx_descriptor.size <= unsigned(slave_i.dat (10 downto 0)); + end if; + end if; + elsif (slave_i.adr(4 downto 2) = "010") then + slave_o.dat (31) <= tx_descriptor.busy; + slave_o.dat (30) <= tx_descriptor.fifo_flow_error; + slave_o.dat (29) <= tx_descriptor.int_flag; + slave_o.dat (26 downto 16) <= std_logic_vector(tx_descriptor.size); --( + slave_o.dat (15 downto 0) <= tx_descriptor.addr; -- + tx_descriptor.int_flag <= '0'; + if (slave_i.we = '1') then + if (tx_descriptor.busy = '0') then + tx_descriptor.busy <= slave_i.dat(31); + tx_descriptor.size <= unsigned(slave_i.dat (26 downto 16)); + tx_descriptor.addr <= slave_i.dat(15 downto 0); + end if; + end if; + elsif (slave_i.adr(4 downto 2) = "011") then + slave_o.dat(31) <= phy_reset; + slave_o.dat (30 downto 4) <= (others => '0'); + slave_o.dat (2 downto 0) <= mii_monitor_o & tx_enable & rx_enable; + phy_reset <= '0'; + if (slave_i.we = '1') then + rst_phy_o <= slave_i.dat(4); + rst_mac_o <= slave_i.dat(3); + mii_monitor_o <= slave_i.dat(2); + tx_enable <= slave_i.dat(1); + rx_enable <= slave_i.dat(0); + end if; + elsif (slave_i.adr(4 downto 2) = "100") then + if (slave_i.we = '1') then + mii_addr_o <= slave_i.dat(4 downto 0); + mii_read_p <= '1'; + end if; + elsif (slave_i.adr(4 downto 2) = "101") then + slave_o.dat (31) <= mii_done; + slave_o.dat (30 downto 16) <= (others => '0'); + slave_o.dat (15 downto 0) <= mii_reg_i; + end if; + end if; + if (rx_pkt_recv_p = '1' and rx_desc_taken = '0') then + rx_descriptor0.busy <= '0'; + rx_descriptor0.int_flag <= '1'; + end if; + if (rx_pkt_recv_p = '1' and rx_desc_taken = '1') then + rx_descriptor1.busy <= '0'; + rx_descriptor1.int_flag <= '1'; + end if; + if (tx_pkt_sent_p = '1') then + tx_descriptor.busy <= '0'; + tx_descriptor.int_flag <= '1'; + end if; + rst_phy_d <= rst_phy_i; + if (rst_phy_i = '0' and rst_phy_d = '1' and mii_monitor_o = '1') then + phy_reset <= '1'; + mii_monitor_o <= '0'; + end if; + end if; + end if; + end process; + +-- rx flux + + process (clk_i) + begin + if rising_edge (clk_i) then + if (rst_i) then + fsm_rx <= idle; + rx_descriptor0.fifo_flow_error <= '0'; + rx_descriptor1.fifo_flow_error <= '0'; + rx_descriptor0.size <= (others => '0'); + rx_descriptor1.size <= (others => '0'); + dma_write_req <= '0'; + else + rx_pkt_recv_p <= '0'; + case (fsm_rx) is + when idle => + rx_pending_o <= '0'; + rx_fifo_ready_o <= '0'; + if (rx_enable = '1' and rx_done_i = '0' and ((rx_descriptor0.busy = '1' or rx_descriptor1.busy = '1') and rx_pkt_recv_p = '0')) then + fsm_rx <= read_word; + if (rx_descriptor0.busy = '1') then + write_addr <= unsigned(rx_descriptor0.addr); + rx_desc_taken <= '0'; + else + write_addr <= unsigned(rx_descriptor1.addr); + rx_desc_taken <= '1'; + end if; + rx_pending_o <= '1'; + rx_bytes <= (others => '0'); + end if; + + when read_word => + rx_fifo_ready_o <= '0'; + if (rx_fifo_valid_i = '1') then + rx_fifo_ready_o <= '1'; + data_rx <= rx_fifo_data_i (31 downto 0); + dma_write_req <= '1'; + fsm_rx <= write_word; + dma_write_bsel <= rx_fifo_data_i (35 downto 32); + rx_bytes <= rx_bytes + f_byte_count (rx_fifo_data_i (35 downto 32)); + if (rx_bytes = to_unsigned(12, 11)) then + rx_ethertype <= rx_fifo_data_i (15 downto 0); + end if; + elsif (rx_done_i = '1') then + fsm_rx <= idle; + -- if (rx_ethertype = c_ETHERTYPE_POWERLINK) then --If a tree falls in a forest and no one is around to hear it, does it make a sound? + rx_pkt_recv_p <= '1'; + -- end if; + if (rx_desc_taken = '0') then + rx_descriptor0.size <= rx_bytes; + rx_descriptor0.fifo_flow_error <= rx_overflow_i; + else + rx_descriptor1.size <= rx_bytes; + rx_descriptor1.fifo_flow_error <= rx_overflow_i; + end if; + end if; + + when write_word => + rx_fifo_ready_o <= '0'; + if (dma_write_done = '1') then + dma_write_req <= '0'; + write_addr <= write_addr + 4; + fsm_rx <= read_word; + end if; + when others => + fsm_rx <= idle; + + end case; + end if; + end if; + end process; + + -- tx flux + + process (clk_i) + begin + if rising_edge (clk_i) then + if (rst_i) then + fsm_tx <= idle; + dma_read_req <= '0'; + else + tx_pkt_sent_p <= '0'; + case (fsm_tx) is + when idle => + tx_pending_o <= '0'; + tx_byte_sel_o <= (others => '0'); + tx_fifo_valid_o <= '0'; + if (tx_enable = '1' and (tx_descriptor.busy = '1' and tx_pkt_sent_p = '0')) then + fsm_tx <= read_word; + read_addr <= unsigned(tx_descriptor.addr); + tx_bytes <= (others => '0'); + + end if; + + when read_word => + tx_fifo_valid_o <= '0'; + + if (tx_bytes (10 downto 2) >= tx_descriptor.size (10 downto 2)) then + if (tx_descriptor.size (1 downto 0) = 0) then + fsm_tx <= idle; + tx_pkt_sent_p <= '1'; + tx_pending_o <= '0'; + + elsif (tx_fifo_valid_o = '1') then + dma_read_req <= '1'; + fsm_tx <= write_partial_word; + end if; + elsif (tx_fifo_ready_i = '1') then + dma_read_req <= '1'; + fsm_tx <= write_word; + + end if; + + when write_word => + --dma_read_req <= '0'; + if (dma_read_done = '1') then + dma_read_req <= '0'; + tx_fifo_valid_o <= '1'; + tx_fifo_data_o <= "1111" & data_tx; + read_addr <= read_addr + 4; + tx_bytes <= tx_bytes + 4; + fsm_tx <= read_word; + end if; + if (tx_bytes (4) = '1') then + tx_pending_o <= '1'; + end if; + when write_partial_word => + --dma_read_req <= '0'; + if (dma_read_done = '1') then + dma_read_req <= '0'; + tx_fifo_valid_o <= '1'; + tx_fifo_data_o <= f_byte_sel(tx_descriptor.size(1 downto 0)) & data_tx; + read_addr <= read_addr + 4; + tx_bytes <= tx_bytes + tx_descriptor.size (1 downto 0); + fsm_tx <= idle; + tx_pkt_sent_p <= '1'; + tx_pending_o <= '0'; + end if; + + when wait_tx_done => + if (tx_done_i = '1') then + fsm_tx <= idle; + end if; + + when others => + fsm_tx <= idle; + + end case; + end if; + end if; + end process; + + master_o.adr(31 downto 16) <= x"8500"; + + process (clk_i) + begin + if rising_edge(clk_i) then + if (rst_i) then + fsm_dma <= idle; + master_o.cyc <= '0'; + master_o.stb <= '0'; + dma_read_done <= '0'; + dma_write_done <= '0'; + else + case (fsm_dma) is + + when idle => + dma_write_done <= '0'; + dma_read_done <= '0'; + if ((dma_read_req and not dma_read_done) or (dma_write_req and not dma_write_done)) then + dma_write <= dma_write_req and not dma_write_done; + dma_read <= dma_read_req and not dma_read_done; + fsm_dma <= transfer; + + end if; + when transfer => + master_o.cyc <= '1'; + master_o.stb <= '1'; + master_o.we <= dma_write; + master_o.sel <= "1111" when (dma_read = '1') else dma_write_bsel; + master_o.adr (15 downto 0) <= std_logic_vector(read_addr) when (dma_read = '1') else std_logic_vector(write_addr); + master_o.dat <= data_rx; + + + data_tx <= master_i.dat; + if (master_i.ack = '1') then + master_o.cyc <= '0'; + master_o.stb <= '0'; + dma_write_done <= dma_write; + dma_read_done <= dma_read; + fsm_dma <= idle; + + end if; + + + when others => + fsm_dma <= idle; + end case; + end if; + end if; + end process; + + + process (clk_i) + begin + if rising_edge(clk_i) then + + if (mii_done_i = '1') then + mii_done <= '1'; + mii_rd_o <= '0'; + mii_reg <= mii_reg_i; + end if; + if (mii_read_p = '1') then + mii_done <= '0'; + mii_rd_o <= '1'; + end if; + end if; + end process; + + end architecture; diff --git a/hdl/urv_core_DTMR.vhd b/hdl/urv_core_DTMR.vhd new file mode 100644 index 0000000000000000000000000000000000000000..9c0cfda5ef6eed2906c1426afd5870584c50e2e8 --- /dev/null +++ b/hdl/urv_core_DTMR.vhd @@ -0,0 +1,472 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +-- +--library smartfusion2; +--use smartfusion2.all; + + +entity urv_core_DTMR is + + generic ( + g_m2s090 : boolean := true; + g_dram_data_width : natural := 39; + g_dram_addr_width : natural := 16 + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + -- to the IRAM primitive + d_iram_i : in std_logic_vector (38 downto 0); + q_iram_o : out std_logic_vector (38 downto 0); + a_iram_o : out std_logic_vector (15 downto 0); + we_iram_o : out std_logic; + re_iram_o : out std_logic; + valid_iram_i : in std_logic; + lock_iram_req_o : out std_logic; + lock_iram_grant_i : in std_logic; + + +-- d_iram_bank1_i : in std_logic_vector (41 downto 0); +-- q_iram_bank1_o : out std_logic_vector (41 downto 0); +-- we_iram_bank1_o : out std_logic; +-- re_iram_bank1_o : out std_logic; +-- valid_iram_bank1_i : in std_logic; +-- lock_iram_req_bank1_o : out std_logic; +-- lock_iram_grant_bank1_i : in std_logic; + + + -- to the DRAM primitive + d_dram_i : in std_logic_vector (g_dram_data_width-1 downto 0); + q_dram_o : out std_logic_vector (g_dram_data_width-1 downto 0); + a_dram_o : out std_logic_vector (g_dram_addr_width-1 downto 0); + we_dram_o : out std_logic; + re_dram_o : out std_logic; + valid_dram_i : in std_logic; + lock_dram_req_o : out std_logic; + lock_dram_grant_i : in std_logic; + + iram_single_error_p_o : out std_logic; + iram_double_error_p_o : out std_logic; + + iram_single_error_bank1_p_o : out std_logic; + iram_double_error_bank1_p_o : out std_logic; + + dram_single_error_p_o : out std_logic; + dram_double_error_p_o : out std_logic; + + irq_i : in std_logic; + -- to the Wishbone xbar + cpu_dwb_o : out t_wishbone_master_out; + cpu_dwb_i : in t_wishbone_master_in + + ); +end entity urv_core_DTMR; + + +architecture rtl of urv_core_DTMR is + component secded_ecc is + generic ( + g_addr_width : natural := 15 + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + -- to the processor/bus + d_i : in std_logic_vector(31 downto 0); + a_i : in std_logic_vector(g_addr_width-1 downto 0); + we_i : in std_logic; + bwe_i : in std_logic_vector (3 downto 0); + re_i : in std_logic; + + q_o : out std_logic_vector(31 downto 0); + done_r_o : out std_logic; + done_w_o : out std_logic; + + --to the BRAM + d_ram_i : in std_logic_vector (38 downto 0); + q_ram_o : out std_logic_vector (38 downto 0); + a_ram_o : out std_logic_vector (g_addr_width-1 downto 0); + we_ram_o : out std_logic; + re_ram_o : out std_logic; + valid_ram_i : in std_logic; + lock_req_o : out std_logic; + lock_grant_i : in std_logic; + + single_error_p_o : out std_logic; + double_error_p_o : out std_logic; + read_fault_p_o : out std_logic; + write_fault_p_o : out std_logic + ); + + + end component; + + component secded_ecc_daec is + generic ( + g_addr_width : natural := 15 + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + -- to the processor/bus + d_i : in std_logic_vector(31 downto 0); + a_i : in std_logic_vector(g_addr_width-1 downto 0); + we_i : in std_logic; + bwe_i : in std_logic_vector (3 downto 0); + re_i : in std_logic; + + q_o : out std_logic_vector(31 downto 0); + done_r_o : out std_logic; + done_w_o : out std_logic; + + --to the BRAM + d_ram_i : in std_logic_vector (41 downto 0); + q_ram_o : out std_logic_vector (41 downto 0); + a_ram_o : out std_logic_vector (g_addr_width-1 downto 0); + we_ram_o : out std_logic; + re_ram_o : out std_logic; + valid_ram_i : in std_logic; + lock_req_o : out std_logic; + lock_grant_i : in std_logic; + + single_error_p_o : out std_logic; + double_error_p_o : out std_logic; + read_fault_p_o : out std_logic; + write_fault_p_o : out std_logic + ); + + + end component; + + + component urv_cpu is + port( + clk_i : in std_logic; + rst_i : in std_logic; + + irq_i : in std_logic; + + im_addr_o : out std_logic_vector(31 downto 0); + im_data_i : in std_logic_vector(31 downto 0); + im_valid_i : in std_logic; + + dm_addr_o : out std_logic_vector(31 downto 0); + dm_data_s_o : out std_logic_vector(31 downto 0); + dm_data_l_i : in std_logic_vector(31 downto 0); + dm_data_select_o : out std_logic_vector(3 downto 0); + --dm_ready_i : in std_logic; + dm_store_o : out std_logic; + dm_load_o : out std_logic; + dm_load_done_i : in std_logic; + dm_store_done_i : in std_logic + ); + end component; + +component rst_filter is + + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + rst_o : out std_logic ); +end component; + + + + signal im_addr, dm_addr, dram_addr : std_logic_vector(31 downto 0); + signal im_data, im_data_cpu, im_data_bank1, dram_data_in, dram_data_out : std_logic_vector(31 downto 0); + signal im_valid, im_valid_cpu, im_valid_bank1 : std_logic; + + signal dm_data_s, dm_data_l, dm_data_ram, dm_wb_rdata : std_logic_vector(31 downto 0); + signal dm_data_select, dram_bwe : std_logic_vector(3 downto 0); + signal dm_load, dm_store, dm_done, dm_ready, dram_we, dram_re : std_logic; + signal dram_done_r, dram_done_w : std_logic; + + signal dm_is_wishbone, dm_cycle_in_progress, dm_load_done_wb, dm_store_done_wb : std_logic; + signal dm_select_wb, dm_wb_write : std_logic; + signal dm_store_done, dm_load_done : std_logic; + signal rst : std_logic; + + attribute syn_hier : string; +attribute syn_hier of rtl: architecture is "fixed"; +begin + + + + filter : rst_filter + port map ( + clk_i => clk_i, + rst_i => rst_i, + rst_o => rst); + + + secded_iram : secded_ecc + generic map ( + g_addr_width => 16 + ) + port map ( + clk_i => clk_i, + rst_i => rst, + + -- to the processor/bus + d_i => (others => '0'), + a_i => im_addr (15 downto 0), + we_i => '0', + bwe_i => (others => '1'), + re_i => '1', + + q_o => im_data, + done_r_o => im_valid, + done_w_o => open, + + --to the BRAM + d_ram_i => d_iram_i, + q_ram_o => q_iram_o, + a_ram_o => a_iram_o, + we_ram_o => we_iram_o, + re_ram_o => re_iram_o, + valid_ram_i => valid_iram_i, + + lock_req_o => lock_iram_req_o, + lock_grant_i => lock_iram_grant_i, + + single_error_p_o => iram_single_error_p_o, + double_error_p_o => iram_double_error_p_o, + read_fault_p_o => open, + write_fault_p_o => open + ); + +gen : if g_m2s090 generate +--secded_iram_bank1 : secded_ecc_daec +-- generic map ( +-- g_addr_width => 15 +-- ) +-- port map ( +-- clk_i => clk_i, +-- rst_i => rst, +-- +-- -- to the processor/bus +-- d_i => (others => '0'), +-- a_i => im_addr (14 downto 0), +-- we_i => '0', +-- bwe_i => (others => '1'), +-- re_i => im_addr(16), +-- +-- q_o => im_data_bank1, +-- done_r_o => im_valid_bank1, +-- done_w_o => open, +-- +-- --to the BRAM +-- d_ram_i => d_iram_bank1_i, +-- q_ram_o => q_iram_bank1_o, +-- a_ram_o => open, +-- we_ram_o => we_iram_bank1_o, +-- re_ram_o => re_iram_bank1_o, +-- valid_ram_i => valid_iram_bank1_i, +-- +-- lock_req_o => lock_iram_req_bank1_o, +-- lock_grant_i => lock_iram_grant_bank1_i, +-- +-- single_error_p_o => iram_single_error_bank1_p_o, +-- double_error_p_o => iram_double_error_bank1_p_o, +-- read_fault_p_o => open, +-- write_fault_p_o => open +-- ); + + + secded_dram : secded_ecc + generic map ( + g_addr_width => 16 + ) + port map ( + clk_i => clk_i, + rst_i => rst, + + -- to the processor/bus + d_i => dram_data_in, + a_i => dram_addr (15 downto 0), + we_i => dram_we and not dram_done_w, + bwe_i => dram_bwe, + re_i => dram_re and not dram_done_r, + + q_o => dram_data_out, + done_r_o => dram_done_r, + done_w_o => dram_done_w, + + --to the BRAM + d_ram_i => d_dram_i, + q_ram_o => q_dram_o, + a_ram_o => a_dram_o, + we_ram_o => we_dram_o, + re_ram_o => re_dram_o, + valid_ram_i => valid_dram_i, + + lock_req_o => lock_dram_req_o, + lock_grant_i => lock_dram_grant_i, + + single_error_p_o => dram_single_error_p_o, + double_error_p_o => dram_double_error_p_o, + read_fault_p_o => open, + write_fault_p_o => open + ); + +end generate; + +gen_daec : if not g_m2s090 generate + + secded_dram : secded_ecc_daec + generic map ( + g_addr_width => 15 + ) + port map ( + clk_i => clk_i, + rst_i => rst, + + -- to the processor/bus + d_i => dram_data_in, + a_i => dram_addr (14 downto 0), + we_i => dram_we and not dram_done_w, + bwe_i => dram_bwe, + re_i => dram_re and not dram_done_r, + + q_o => dram_data_out, + done_r_o => dram_done_r, + done_w_o => dram_done_w, + + --to the BRAM + d_ram_i => d_dram_i, + q_ram_o => q_dram_o, + a_ram_o => a_dram_o, + we_ram_o => we_dram_o, + re_ram_o => re_dram_o, + valid_ram_i => valid_dram_i, + + lock_req_o => lock_dram_req_o, + lock_grant_i => lock_dram_grant_i, + + single_error_p_o => dram_single_error_p_o, + double_error_p_o => dram_double_error_p_o, + read_fault_p_o => open, + write_fault_p_o => open + ); + +end generate; + + dm_is_wishbone <= dm_addr(31); + + -- Wishbone bus arbitration / internal RAM access + process(clk_i) + begin + if rising_edge(clk_i) then + if(rst = '1') then + cpu_dwb_o.cyc <= '0'; + dm_cycle_in_progress <= '0'; + dm_load_done_wb <= '0'; + dm_store_done_wb <= '0'; + dm_select_wb <= '0'; + cpu_dwb_o.cyc <= '0'; + cpu_dwb_o.stb <= '0'; + dram_we <= '0'; + dram_re <= '0'; + dram_addr <= (others => '0'); + else + -- signals from uRV data interface to the data-ram are sampled to improve fmax + if (dram_done_r or dram_done_w) then + dram_we <= '0'; + dram_re <= '0'; + end if; + + if (dm_is_wishbone = '0' and (dm_load = '1' or dm_store = '1')) then + dram_addr <= dm_addr; + dram_data_in <= dm_data_s; + dram_bwe <= dm_data_select; + dram_we <= dm_store; + dram_re <= dm_load; + dm_select_wb <= '0'; + end if; + + + if(dm_cycle_in_progress = '0') then + dm_select_wb <= '0'; + if(dm_is_wishbone = '1' and (dm_load = '1' or dm_store = '1')) then + cpu_dwb_o.cyc <= '1'; + cpu_dwb_o.stb <= '1'; + cpu_dwb_o.we <= dm_store; + dm_wb_write <= dm_store; + + cpu_dwb_o.adr <= dm_addr; + cpu_dwb_o.dat <= dm_data_s; + cpu_dwb_o.sel <= dm_data_select; + + + dm_load_done_wb <= '0'; + dm_store_done_wb <= '0'; + dm_cycle_in_progress <= '1'; + else + dm_store_done_wb <= '0'; + dm_load_done_wb <= '0'; + dm_cycle_in_progress <= '0'; + end if; + + else + if(cpu_dwb_i.stall = '0') then + cpu_dwb_o.stb <= '0'; + end if; + + if(cpu_dwb_i.ack = '1') then + if(dm_wb_write = '0') then + dm_wb_rdata <= cpu_dwb_i.dat; + dm_load_done_wb <= '1'; + else + dm_store_done_wb <= '1'; + end if; + dm_select_wb <= '1'; + dm_cycle_in_progress <= '0'; + cpu_dwb_o.cyc <= '0'; + end if; + end if; + end if; + end if; + end process; + + + dm_store_done <= dm_store_done_wb when (dm_select_wb = '1') else dram_done_w; + dm_load_done <= dm_load_done_wb when (dm_select_wb = '1') else dram_done_r; + dm_data_l <= dm_wb_rdata when (dm_select_wb = '1') else dram_data_out; +-- +-- im_data_cpu <= im_data when im_addr(16) = '0' else im_data_bank1; +-- im_valid_cpu <= im_valid when im_addr(16) = '0' else im_valid_bank1; + + cpu_core : urv_cpu + port map ( + clk_i => clk_i, + rst_i => rst, + irq_i => irq_i, + im_addr_o => im_addr, + im_data_i => im_data, + im_valid_i => im_valid, + dm_addr_o => dm_addr, + dm_data_s_o => dm_data_s, + dm_data_l_i => dm_data_l, + dm_data_select_o => dm_data_select, + -- dm_ready_i => '1', + dm_store_o => dm_store, + dm_load_o => dm_load, + dm_load_done_i => dm_load_done, + dm_store_done_i => dm_store_done); + + +end architecture; \ No newline at end of file diff --git a/hdl/urv_soc.vhd b/hdl/urv_soc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..43683dbf66aa293720c0a2dd649f289f306726ca --- /dev/null +++ b/hdl/urv_soc.vhd @@ -0,0 +1,950 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use STD.textio.all; + + +library work; +use work.wishbone_pkg.all; + + + +use work.voter.ALL; +use work.wb_master_voter_pkg.all; +use work.wb_slave_voter_pkg.all; + +entity urv_soc is + + port ( + clk_i : in std_logic; + clk_ram_i : in std_logic_vector (39 downto 0); + rst_i : in std_logic; + + DEVRST_I : in std_logic; + + + apb_psel_o : out std_logic; + apb_pwr_o : out std_logic; + apb_pen_o : out std_logic; + apb_paddr_o : out std_logic_vector(31 downto 0); + apb_pwdat_o : out std_logic_vector(31 downto 0); + apb_prdat_i : in std_logic_vector(31 downto 0); + apb_pready_i : in std_logic; -- + apb_pslverr_i : in std_logic; -- + + + uart_tx_o : out std_logic; + + + --TX + eth_tx_clk_i : in std_logic; + eth_txd_o : out std_logic_vector (3 downto 0); + eth_txen_o : out std_logic; + eth_txerr_o : out std_logic; + + --RX + eth_rx_clk_i : in std_logic; + eth_rxd_i : in std_logic_vector (3 downto 0); + eth_rxdv_i : in std_logic; + eth_rxerr_i : in std_logic; + + + --MIIM + eth_mdc_o : out std_logic; + eth_md_i : in std_logic; + eth_md_o : out std_logic; + eth_oe_o : out std_logic; + + eth_rst_o : out std_logic; + + reboot_o : out std_logic + ); +end entity urv_soc; + + +architecture rtl of urv_soc is + + +constant g_dram_data_width : integer := 39; +constant g_dram_addr_width : integer := 16; +constant g_m2s090 : boolean := true; + + function f_voter_stdlogic (a : std_logic; b : std_logic; c : std_logic) return std_logic is + begin + return (a and b) or (a and c) or (b and c); + end f_voter_stdlogic; + + + component uart + port ( + reset_i : in std_logic; + clk_i : in std_logic; + txd_o : out std_logic; + tx_data_i : in std_logic_vector(7 downto 0); + tx_wdone_o : out std_logic; + tx_ready_o : out std_logic; + tx_req_i : in std_logic); + end component; + + + component xwb_uart + + port( + clk_sys_i : in std_logic; + rst_i : in std_logic; + + -- Wishbone + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; + +-- Port for BIT field: 'TX busy' in reg: 'Status Register' + uart_sr_tx_busy_i : in std_logic; +-- Port for MONOSTABLE field: 'TX trigger' in reg: 'Status Register' + uart_sr_tx_send_o : out std_logic; + uart_tdr_tx_data_o : out std_logic_vector(7 downto 0) + + ); + + end component; + + + component xwb_seu_regs + + port( + clk_sys_i : in std_logic; + rst_i : in std_logic; + + -- Wishbone + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; + + + iram_seu_regs_see_se_i : in std_logic_vector(15 downto 0); + iram_seu_regs_see_de_i : in std_logic_vector(15 downto 0); + dram_seu_regs_see_se_i : in std_logic_vector(15 downto 0); + dram_seu_regs_see_de_i : in std_logic_vector(15 downto 0) + ); + + end component; + + + component xwb_wd_reg + + port( + clk_sys_i : in std_logic; + rst_i : in std_logic; + + -- Wishbone + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; + -- Port for MONOSTABLE field: 'Heartbeat' in reg: 'Watchdog' + wd_reg_heartbeat_o : out std_logic + ); + + end component; + + + + component xwb_ram_adapter + + generic ( + g_addr_width : natural := 15; + g_data_width :natural := 38; + g_is_iram : boolean := false; + g_is_dram : boolean := false + + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + boot_done_i : in std_logic; + + -- Wishbone + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + + -- ram interface + d_ram_i : in std_logic_vector (g_data_width-1 downto 0); + q_ram_o : out std_logic_vector (g_data_width-1 downto 0); + a_ram_o : out std_logic_vector (g_addr_width-1 downto 0); + we_ram_o : out std_logic; + re_ram_o : out std_logic; + valid_ram_i : in std_logic; + lock_req_o : out std_logic; + lock_grant_i : in std_logic; + single_error_p_o : out std_logic; + double_error_p_o : out std_logic + + ); + end component; + + + + component dpram_generic + + generic ( + g_addr_width : natural := 15; + g_data_width : natural := 38 + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + clk_ram_i : in std_logic_vector (39 downto 0); + da_i : in std_logic_vector(g_data_width-1 downto 0); + db_i : in std_logic_vector(g_data_width-1 downto 0); + aa_i : in std_logic_vector(g_addr_width-1 downto 0); + ab_i : in std_logic_vector(g_addr_width-1 downto 0); + wa_i : in std_logic_vector (3 downto 1); + wb_i : in std_logic; + ra_i : in std_logic; + rb_i : in std_logic; + + qa_o : out std_logic_vector(g_data_width-1 downto 0); + qb_o : out std_logic_vector(g_data_width-1 downto 0); + + lock_a_req_i : in std_logic; + lock_b_req_i : in std_logic; + lock_a_grant_o : out std_logic; + lock_b_grant_o : out std_logic; + + valid_a_o : out std_logic; + valid_b_o : out std_logic + + + ); + end component; + + + + + component ram_voter + generic ( + g_addr_width : natural := 15; + g_data_width : natural := 38 + + ); + port ( + + + da_vot_i : in t_voter_stdvector; + aa_vot_i : in t_voter_stdvector; + wa_vot_i : in t_voter_stdlogic; + ra_vot_i : in t_voter_stdlogic; + + lock_a_req_vot_i : in t_voter_stdlogic; + + da_o : out std_logic_vector(g_data_width-1 downto 0); + aa_o : out std_logic_vector(g_addr_width-1 downto 0); + wa_o : out std_logic; + ra_o : out std_logic; + lock_a_req_o : out std_logic + ); + + + end component; + + + + +component seu_counters is + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + event_se_iram : in std_logic; + event_de_iram : in std_logic; + event_se_dram : in std_logic; + event_de_dram : in std_logic; + + + se_dram_o : out std_logic_vector (15 downto 0); + de_dram_o : out std_logic_vector (15 downto 0); + + se_iram_o : out std_logic_vector (15 downto 0); + de_iram_o : out std_logic_vector (15 downto 0) + + ); + +end component; + + + constant c_SLAVE_NUM : natural := 7; + -- only one master to reduce LUT + -- tested in radiation also with 2 masters, no problems + constant c_MASTER_NUM : natural := 1; + + constant c_SLAVE_WD : integer := 0; + constant c_SLAVE_UART : integer := 1; + constant c_SLAVE_SEC : integer := 2; + constant c_SLAVE_ETH : integer := 3; + constant c_SLAVE_DRAM : integer := 4; + constant c_SLAVE_SUPERVISOR : integer := 5; + constant c_SLAVE_ENVM : integer := 6; + + constant c_CNX_ADDRESS : t_wishbone_address_array(c_SLAVE_NUM-1 downto 0) := ( + c_SLAVE_WD => x"81000000", + c_SLAVE_UART => x"82000000", + c_SLAVE_SEC => x"83000000", + c_SLAVE_ETH => x"84000000", + c_SLAVE_DRAM => x"85000000", + c_SLAVE_SUPERVISOR => x"86000000", + c_SLAVE_ENVM => x"87000000" + ); + + constant c_CNX_MASK : t_wishbone_address_array(c_SLAVE_NUM-1 downto 0) := ( + c_SLAVE_WD => x"ff000000", + c_SLAVE_UART => x"ff000000", + c_SLAVE_SEC => x"ff000000", + c_SLAVE_ETH => x"FF000000", + c_SLAVE_DRAM => x"FF000000", + c_SLAVE_SUPERVISOR => x"ff000000", + c_SLAVE_ENVM => x"FF000000" + + ); + + signal cnx_master_in : t_wishbone_master_in_array(c_SLAVE_NUM-1 downto 0); + signal cnx_master_out : t_wishbone_master_out_array(c_SLAVE_NUM-1 downto 0); + signal cnx_slave_in : t_wishbone_slave_in_array(c_MASTER_NUM-1 downto 0); + signal cnx_slave_out : t_wishbone_slave_out_array(c_MASTER_NUM-1 downto 0); + + + signal cpu_dwb_out_voted : t_wishbone_master_out; + signal cpu_dwb_out : t_voter_wb_master; + signal cpu_dwb_in : t_wishbone_master_in; + + signal envm_wb_iram_in: t_wishbone_slave_in; + signal envm_wb_iram_out : t_wishbone_slave_out; + + signal eth_m_wb_out : t_wishbone_master_out; + signal eth_m_wb_in : t_wishbone_master_in; + + signal supervisor_wb_out : t_voter_wb_slave; + signal rst_cpu_sv, reboot_sv, boot_done_sv : std_logic_vector (3 downto 1); + signal rst_cpu_sv_voted, reboot_sv_voted : std_logic; + signal boot_done : std_logic; + + signal cpu_rst, cpu_rst_d : std_logic; + + + + signal first_de : std_logic; + + signal de_counter, se_counter : unsigned (15 downto 0); + + type fsm_uart_states is (idle, wait_write, wait_lf); + signal fsm_uart : fsm_uart_states := idle; + + signal uart_ready, uart_ready_wb, dm_uart_write_done : std_logic; + signal uart_tx_data, uart_tx_data_wb : std_logic_vector (7 downto 0); + signal dm_counter_read_done, dm_uart_read_done : std_logic; + + signal rst_cpu, rst_cpu_boot, rst_cpu_wd : std_logic; + signal wd_counter : unsigned (28 downto 0); + signal dm_counter_write_done : std_logic; + + signal wd_heartbeat : std_logic; + + signal tx_req, tx_req_wb : std_logic; + + + signal q_cpu_iram : t_voter_stdvector (open)(38 downto 0); + signal q_cpu_dram : t_voter_stdvector(open)(g_dram_data_width-1 downto 0); + signal a_cpu_iram : t_voter_stdvector (open)(15 downto 0); + signal a_cpu_dram : t_voter_stdvector (open)(g_dram_addr_width-1 downto 0); + signal we_cpu_iram, we_cpu_dram : std_logic_vector (3 downto 1); + signal re_cpu_iram, re_cpu_dram : t_voter_stdlogic; + signal lock_cpu_dram_req, lock_cpu_iram_req : t_voter_stdlogic; +signal selector : std_logic; + signal d_cpu_iram, d_wb_iram, d_cpu_iram_seu : std_logic_vector (38 downto 0); + signal d_cpu_dram, d_wb_dram : std_logic_vector (g_dram_data_width-1 downto 0); + signal q_cpu_iram_voted, q_wb_iram : std_logic_vector (38 downto 0); +signal q_cpu_dram_voted, q_wb_dram : std_logic_vector (g_dram_data_width-1 downto 0); + + signal a_cpu_iram_voted, a_wb_iram : std_logic_vector (15 downto 0); + signal a_cpu_dram_voted, a_wb_dram : std_logic_vector (g_dram_addr_width-1 downto 0); + signal re_cpu_iram_voted, re_cpu_dram_voted, re_wb_dram, re_wb_iram : std_logic; + signal we_cpu_iram_voted, we_cpu_dram_voted, we_wb_dram, we_wb_iram : std_logic; + signal lock_cpu_dram_req_voted, lock_wb_dram_req, lock_cpu_dram_grant, lock_wb_dram_grant : std_logic; + signal lock_cpu_iram_req_voted, lock_wb_iram_req, lock_wb_iram_grant, lock_cpu_iram_grant : std_logic; + signal valid_cpu_iram, valid_cpu_dram, valid_wb_iram, valid_wb_dram : std_logic; + + signal se_iram, se_dram : std_logic_vector (1 to 3); + signal de_iram, de_dram : std_logic_vector (1 to 3); + + signal se_iram_voted, se_dram_voted, de_iram_voted, de_dram_voted : std_logic; + signal se_iram_scrubber, de_iram_scrubber : std_logic; + signal se_dram_scrubber, de_dram_scrubber : std_logic; + + signal reboot_board, reboot_board_f : std_logic; + + signal irq_eth : std_logic; + signal uart_debug_ready, tx_debug_req : std_logic; + signal uart_debug_data : std_logic_vector (7 downto 0); + signal se_iram_counts, de_iram_counts, se_dram_counts, de_dram_counts : std_logic_vector (15 downto 0); + + + signal first_time : std_logic; + + attribute syn_radhardlevel : string; + attribute syn_radhardlevel of rtl : architecture is "tmr"; + + begin + + rst_cpu <= rst_cpu_boot; + + reboot_board <= rst_cpu_wd or reboot_sv_voted; --(not rst_cpu and (de_iram_voted or de_dram_voted or de_iram_scrubber or de_dram_scrubber)) ; + reboot_o <= reboot_board; + + + + iram : dpram_generic + generic map ( + g_addr_width => 16, + g_data_width => 39) + port map ( + clk_i => clk_i, + clk_ram_i => clk_ram_i, + rst_i => rst_i, + da_i => q_cpu_iram_voted, + db_i => q_wb_iram, + aa_i => a_cpu_iram_voted, + ab_i => a_wb_iram, + wa_i => we_cpu_iram,--we_cpu_iram_voted, + wb_i => we_wb_iram, + ra_i => re_cpu_iram_voted, + rb_i => re_wb_iram, + + lock_a_req_i => lock_cpu_iram_req_voted, + lock_b_req_i => lock_wb_iram_req, + lock_a_grant_o => lock_cpu_iram_grant, + lock_b_grant_o => lock_wb_iram_grant, + + qa_o => d_cpu_iram, + qb_o => d_wb_iram, + valid_a_o => valid_cpu_iram, + valid_b_o => valid_wb_iram + + ); + + + + iram_voter : ram_voter + generic map( + g_addr_width => 16, + g_data_width => 39 + ) + port map ( + da_vot_i => q_cpu_iram, + aa_vot_i => a_cpu_iram, + wa_vot_i => (others => '0'), --we_cpu_iram, + ra_vot_i => re_cpu_iram, + + lock_a_req_vot_i => lock_cpu_iram_req, + lock_a_req_o => lock_cpu_iram_req_voted, + + da_o => q_cpu_iram_voted, + aa_o => a_cpu_iram_voted, + -- wa_o => we_cpu_iram_voted, + ra_o => re_cpu_iram_voted + + ); + + + dram : dpram_generic + generic map ( + g_addr_width => g_dram_addr_width, + g_data_width => g_dram_data_width) + port map ( + clk_i => clk_i, + clk_ram_i => clk_ram_i, + rst_i => rst_i, + da_i => q_cpu_dram_voted, + db_i => q_wb_dram, + aa_i => a_cpu_dram_voted, + ab_i => a_wb_dram, + wa_i => we_cpu_dram,--we_cpu_dram_voted, + wb_i => we_wb_dram, + ra_i => re_cpu_dram_voted, + rb_i => re_wb_dram, + + + lock_a_req_i => lock_cpu_dram_req_voted, + lock_b_req_i => lock_wb_dram_req, + lock_a_grant_o => lock_cpu_dram_grant, + lock_b_grant_o => lock_wb_dram_grant, + + qa_o => d_cpu_dram, + qb_o => d_wb_dram, + valid_a_o => valid_cpu_dram, + valid_b_o => valid_wb_dram + + + ); + + + + dram_voter : ram_voter + generic map( + g_addr_width => g_dram_addr_width, + g_data_width => g_dram_data_width) + port map ( + da_vot_i => q_cpu_dram, + aa_vot_i => a_cpu_dram, + wa_vot_i => (others => '0'), --we_cpu_dram, + ra_vot_i => re_cpu_dram, + + lock_a_req_vot_i => lock_cpu_dram_req, + lock_a_req_o => lock_cpu_dram_req_voted, + + da_o => q_cpu_dram_voted, + aa_o => a_cpu_dram_voted, + --wa_o => we_cpu_dram_voted, + ra_o => re_cpu_dram_voted + ); + + + + + gen_cores : for k in 1 to 3 generate + + urv_core : entity work.urv_core_DTMR + + generic map( + g_m2s090 => g_m2s090, + g_dram_data_width => g_dram_data_width, + g_dram_addr_width => g_dram_addr_width + ) + port map ( + clk_i => clk_i, + rst_i => rst_cpu or rst_cpu_sv (k), --(1)rst_cpu_sv(k), --rst_cpu, + + -- to the IRAM primitive + d_iram_i => d_cpu_iram, + q_iram_o => q_cpu_iram(k), + a_iram_o => a_cpu_iram(k), + we_iram_o => we_cpu_iram(k), + re_iram_o => re_cpu_iram(k), + valid_iram_i => valid_cpu_iram, + lock_iram_req_o => lock_cpu_iram_req(k), + lock_iram_grant_i => lock_cpu_iram_grant, + + + + -- to the DRAM primitive + d_dram_i => d_cpu_dram, + q_dram_o => q_cpu_dram(k), + a_dram_o => a_cpu_dram(k), + we_dram_o => we_cpu_dram(k), + re_dram_o => re_cpu_dram(k), + valid_dram_i => valid_cpu_dram, + lock_dram_req_o => lock_cpu_dram_req(k), + lock_dram_grant_i => lock_cpu_dram_grant, + + iram_single_error_p_o => se_iram(k), + iram_double_error_p_o => de_iram(k), + + dram_single_error_p_o => se_dram(k), + dram_double_error_p_o => de_dram(k), + irq_i => irq_eth, + -- to the Wishbone xbar + cpu_dwb_o => cpu_dwb_out(k), + cpu_dwb_i => cpu_dwb_in + + ); + + supervisor : entity work.urv_supervisor + generic map ( + g_cpu_id => k) + port map( + clk_i => clk_i, + rst_i => rst_i, + + slave_i => cnx_master_out(c_SLAVE_SUPERVISOR), + slave_o => supervisor_wb_out (k), + + pc_i => a_cpu_iram, + stall_i => ('0', '0', '0'), + boot_done_o => boot_done_sv (k), + rst_cpu_o => rst_cpu_sv (k), + reboot_o => reboot_sv (k) + + ); + + + end generate; + + wb_cpu_voter : entity work.wb_master_voter + port map ( + m_wb_i => cpu_dwb_out, + m_wb_o => cpu_dwb_out_voted + ); + + wb_supervisor_voter : entity work.wb_slave_voter + port map ( + s_wb_i => supervisor_wb_out, + s_wb_o => cnx_master_in(c_SLAVE_SUPERVISOR) + ); + + reboot_sv_voted <= f_voter_stdlogic (reboot_sv(1), reboot_sv(2), reboot_sv(3)); + boot_done <= f_voter_stdlogic (boot_done_sv (1), boot_done_sv(2),boot_done_sv(3)); + + se_iram_voted <= f_voter_stdlogic(se_iram (1), se_iram(2), se_iram(3)); + se_dram_voted <= f_voter_stdlogic(se_dram (1), se_dram(2), se_dram(3)); + de_iram_voted <= f_voter_stdlogic(de_iram (1), de_iram(2), de_iram(3)); + de_dram_voted <= f_voter_stdlogic(de_dram (1), de_dram(2), de_dram(3)); + + + envm_wb : entity work.wb_envm + port map ( + clk_i => clk_i, + rst_i => rst_i, + rst_cpu_o => rst_cpu_boot, + + apb_psel_o => apb_psel_o, + apb_pwr_o => apb_pwr_o, + apb_pen_o => apb_pen_o, + apb_paddr_o => apb_paddr_o, + apb_pwdat_o => apb_pwdat_o, + apb_prdat_i => apb_prdat_i, + apb_pready_i => apb_pready_i, + + master_i => envm_wb_iram_out, + master_o => envm_wb_iram_in, + + slave_i => cnx_master_out (c_SLAVE_ENVM), + slave_o => cnx_master_in (c_SLAVE_ENVM) + ); + + + + + xwb_iram : xwb_ram_adapter + generic map ( + g_addr_width => 16, + g_data_width => 39, + g_is_iram => true, + g_is_dram => false + ) + port map( + clk_i => clk_i, + rst_i => rst_i, + boot_done_i => boot_done, + + -- Wishbone + slave_i => envm_wb_iram_in, + slave_o => envm_wb_iram_out, + + -- ram interface + d_ram_i => d_wb_iram, + q_ram_o => q_wb_iram, + a_ram_o => a_wb_iram, + we_ram_o => we_wb_iram, + re_ram_o => re_wb_iram, + valid_ram_i => valid_wb_iram, + lock_req_o => lock_wb_iram_req, + lock_grant_i => lock_wb_iram_grant, + single_error_p_o => se_iram_scrubber, + double_error_p_o => de_iram_scrubber + ); + + + + + + + + xwb_dram : xwb_ram_adapter + generic map ( + g_addr_width => g_dram_addr_width, + g_data_width => g_dram_data_width, + g_is_iram => false, + g_is_dram => true + ) + port map( + clk_i => clk_i, + rst_i => rst_i, + boot_done_i => boot_done, + + -- Wishbone + slave_i => eth_m_wb_out, --cnx_master_out(c_SLAVE_DRAM), + slave_o => eth_m_wb_in,--cnx_master_in(c_SLAVE_DRAM), + + -- ram interface + d_ram_i => d_wb_dram, + q_ram_o => q_wb_dram, + a_ram_o => a_wb_dram, + we_ram_o => we_wb_dram, + re_ram_o => re_wb_dram, + valid_ram_i => valid_wb_dram, + lock_req_o => lock_wb_dram_req, + lock_grant_i => lock_wb_dram_grant, + single_error_p_o => se_dram_scrubber, + double_error_p_o => de_dram_scrubber + ); + + + + + + U_Local_Interconnect : xwb_crossbar + generic map ( + g_NUM_MASTERS => 1, + g_NUM_SLAVES => c_SLAVE_NUM, + g_REGISTERED => true, + g_ADDRESS => c_CNX_ADDRESS, + g_MASK => c_CNX_MASK) + port map ( + clk_sys_i => clk_i, + rst_n_i => not rst_i, + slave_i => cnx_slave_in, --cpu_dwb_out, + slave_o => cnx_slave_out, --cpu_dwb_in, + master_i => cnx_master_in, + master_o => cnx_master_out); + + cnx_slave_in(0) <= cpu_dwb_out_voted; + cpu_dwb_in <= cnx_slave_out(0); + + +mac : entity work.ueth +port map ( + + clk_i => clk_i, + rst_i => rst_i, + + --TX + phy0_tx_clk_i => eth_tx_clk_i, + phy0_txd_o => eth_txd_o, + phy0_txen_o => eth_txen_o, + -- phy0_txerr_o => eth_txerr_o, + + --RX + phy0_rx_clk_i => eth_rx_clk_i, + phy0_rxd_i => eth_rxd_i, + phy0_rxdv_i => eth_rxdv_i, + phy0_rxerr_i => eth_rxerr_i, + + --TX + phy1_tx_clk_i => eth_tx_clk_i, + phy1_txd_o => open, + phy1_txen_o => open, + -- phy1_txerr_o => open, + + --RX + phy1_rx_clk_i => eth_rx_clk_i, + phy1_rxd_i => (others =>'0'), + phy1_rxdv_i => '0', + phy1_rxerr_i => '0', + + + --MIIM + phy_mdc_o => eth_mdc_o, + phy_md_i => eth_md_i, + phy_md_o => eth_md_o, + phy_oe_o => eth_oe_o, + + phy_rst_o => eth_rst_o, + irq_o => irq_eth, + -- Wishbone regs + slave_i => cnx_master_out(c_SLAVE_ETH), + slave_o => cnx_master_in(c_SLAVE_ETH), + + -- Wishbone DMA + master_i => eth_m_wb_in, + master_o => eth_m_wb_out + +); + + + + + + U_seu_regs : xwb_seu_regs + port map( + clk_sys_i => clk_i, + rst_i => rst_i, + + -- Wishbone + slave_i => cnx_master_out(c_SLAVE_SEC), + slave_o => cnx_master_in(c_SLAVE_SEC), + + iram_seu_regs_see_se_i => se_iram_counts, + iram_seu_regs_see_de_i => de_iram_counts, + dram_seu_regs_see_se_i => se_dram_counts, + dram_seu_regs_see_de_i => de_dram_counts + ); + + inst_seu_counters: seu_counters + + port map( + clk_i => clk_i, + rst_i => rst_i, + + event_se_iram => se_iram_voted or se_iram_scrubber, + event_de_iram => de_iram_voted or de_iram_scrubber, + + event_se_dram => se_dram_voted or se_dram_scrubber, + event_de_dram => de_dram_voted or de_dram_scrubber, + + + se_iram_o => se_iram_counts, + de_iram_o => de_iram_counts, + se_dram_o => se_dram_counts, + de_dram_o => de_dram_counts + + + + ); + + + + U_wd_regs : xwb_wd_reg + port map( + clk_sys_i => clk_i, + rst_i => rst_i, + + -- Wishbone + slave_i => cnx_master_out(c_SLAVE_WD), + slave_o => cnx_master_in(c_SLAVE_WD), + + wd_reg_heartbeat_o => wd_heartbeat + ); + + + + + wd : process (clk_i) + begin + if rst_i = '1' then + rst_cpu_wd <= '0'; + wd_counter <= (others => '0'); + elsif rising_edge(clk_i) then + rst_cpu_wd <= '0'; + + wd_counter <= wd_counter + 1; + + if (wd_heartbeat = '1') then + wd_counter <= (others => '0'); + end if; + if (wd_counter = (wd_counter'range => '1')) then + rst_cpu_wd <= '1'; + end if; + end if; + end process; + + + + + U_UART_regs : xwb_uart + + port map ( + clk_sys_i => clk_i, + rst_i => rst_i, + slave_i => cnx_master_out(c_SLAVE_UART), + slave_o => cnx_master_in(c_SLAVE_UART), + uart_sr_tx_busy_i => uart_ready_wb, + uart_sr_tx_send_o => tx_req_wb, + uart_tdr_tx_data_o => uart_tx_data_wb + ); + + uart_tx : uart + port map ( + reset_i => devrst_i, + clk_i => clk_i, + txd_o => uart_tx_o, + tx_data_i => uart_tx_data, + tx_wdone_o => dm_uart_write_done, + tx_ready_o => uart_ready, + tx_req_i => tx_req); + + + process (clk_i) + begin + if devrst_i = '1' then + first_time <= '1'; + uart_ready_wb <= '0'; + fsm_uart <= idle; + tx_req <= '0'; + first_de <= '1'; + elsif rising_edge (clk_i) then + if (rst_i) then + first_de <= '1'; + + end if; + case (fsm_uart) is + when idle => + uart_ready_wb <= uart_ready; + tx_req <= tx_req_wb; + uart_tx_data <= uart_tx_data_wb; + + if (first_de and (de_iram_voted or de_dram_voted or de_iram_scrubber or de_iram_scrubber)) then + fsm_uart <= wait_write; + uart_tx_data <= x"23"; -- 23# + tx_req <= '1'; + first_de <= '0'; + end if; + if (reboot_sv_voted = '1') then + fsm_uart <= wait_write; + uart_tx_data <= x"24"; -- $ + tx_req <= '1'; + end if; + if (rst_i = '1') then + -- fsm_uart <= wait_write; + -- uart_tx_data <= x"25"; -- % + -- tx_req <= '1'; + end if; + if (first_time = '1') then + first_time <= '0'; + uart_tx_data <= x"40"; -- @ + tx_req <= '1'; + fsm_uart <= wait_write; + end if; + + + when wait_write => + if (uart_ready = '1') then + tx_req <= '1'; + uart_tx_data <= x"0A"; + fsm_uart <= wait_lf; + end if; + + when wait_lf => + if (uart_ready = '1') then + tx_req <= '0'; + fsm_uart <= idle; + end if; + when others => fsm_uart <= idle; + end case; + end if; + end process; + + + + + -- synthesis translate_off + + + process + begin + loop + wait until rising_edge(clk_i); + if (tx_req = '1') then + --std.textio.write(std.textio.output, to_string(uart_tx_data)); + + + WRITE (output, (1 => character'val (to_integer(unsigned(uart_tx_data))))); + end if; + + end loop; + end process; + -- synthesis translate_on + + + + + + end architecture; \ No newline at end of file diff --git a/hdl/urv_supervisor.vhd b/hdl/urv_supervisor.vhd new file mode 100644 index 0000000000000000000000000000000000000000..4c5f0a0a0298237754007fc191e634a52020d2bd --- /dev/null +++ b/hdl/urv_supervisor.vhd @@ -0,0 +1,180 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; + +--library smartfusion2; +--use smartfusion2.all; + +use work.voter.all; +use work.wb_voter_pkg.all; + + + +entity urv_supervisor is +generic ( + g_cpu_id : natural ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + + pc_i : in t_voter_stdvector (open)(15 downto 0); + stall_i : in t_voter_stdlogic; + + rst_cpu_o : out std_logic; + reboot_o : out std_logic; + boot_done_o : out std_logic + + ); + +end entity urv_supervisor; + +architecture rtl of urv_supervisor is + + signal rst_cpu : std_logic; + signal pc_cpu1_ok : std_logic; + signal pc_cpu2_ok : std_logic; + signal pc_cpu3_ok : std_logic; + signal panic, panic_d : std_logic; + + signal state_cpu_1, state_cpu_2, state_cpu_3 : std_logic; + signal state_cpu : std_logic_vector (3 downto 1); + signal release_cpu : std_logic; + + type fsm_states is (boot, boot_cnt, voting, lock_step, fatal, fatal_2); + constant recovery_dunc : std_logic_vector (15 downto 0) := x"0000"; + signal fsm : fsm_states := voting; + + signal start_recovery : std_logic; + signal count : unsigned (2 downto 0); + + +attribute syn_encoding : string; +attribute syn_encoding of fsm : signal is "safe,onehot"; + + attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; +begin + + rst_cpu_o <= rst_cpu; + + + + pc_cpu1_ok <= '1' when ((pc_i(1) = pc_i(2)) or (pc_i(1) = pc_i(3))) else '0'; + pc_cpu2_ok <= '1' when ((pc_i(2) = pc_i(1)) or (pc_i(2) = pc_i(3))) else '0'; + pc_cpu3_ok <= '1' when ((pc_i(3) = pc_i(2)) or (pc_i(3) = pc_i(1))) else '0'; + + panic <= not (pc_cpu1_ok or pc_cpu2_ok or pc_cpu3_ok); + + state_cpu (1) <= state_cpu_1; + state_cpu (2) <= state_cpu_2; + state_cpu (3) <= state_cpu_3; + + process (clk_i) + begin + if rising_edge (clk_i) then + if (rst_cpu) then + panic_d <= '0'; + else + panic_d <= panic; + + end if; + end if; + end process; + + process (clk_i) + begin + if rising_edge (clk_i) then + if rst_i = '1' then + fsm <= boot; + reboot_o <= '0'; + rst_cpu <= '1'; + count <= (others => '0'); + else + case fsm is + when boot => + state_cpu_1 <= '1'; + state_cpu_2 <= '1'; + state_cpu_3 <= '1'; + rst_cpu <= '1'; + reboot_o <= '0'; + fsm <= boot_cnt; + count <= (others => '0'); + when boot_cnt => + count <= count + 1; + if (count (2)) then + fsm <= voting; + end if; + when voting => + rst_cpu <= '0'; + if (pc_cpu1_ok = '0') then + fsm <= lock_step; + state_cpu_1 <= '0'; + end if; + if (pc_cpu2_ok = '0') then + fsm <= lock_step; + state_cpu_2 <= '0'; + end if; + if (pc_cpu3_ok = '0') then + fsm <= lock_step; + state_cpu_3 <= '0'; + end if; + if (panic_d = '1' and panic = '1') then + fsm <= fatal; + end if; + + + when lock_step => + rst_cpu <= not state_cpu(g_cpu_id); + + if (start_recovery = '1') then + fsm <= boot; + end if; + + if (panic_d = '1' and panic = '1') then + fsm <= fatal; + end if; + when fatal => + rst_cpu <= '1'; + state_cpu_1 <= '0'; + state_cpu_2 <= '0'; + state_cpu_3 <= '0'; + reboot_o <= '1'; + fsm <= fatal_2; + when fatal_2 => + fsm <= boot; + when others => + fsm <= boot; + end case; + end if; + end if; + end process; + + + xwb_reg : entity work.xwb_supervisor_reg + port map ( + rst_i => rst_i, + clk_sys_i => clk_i, + + -- Wishbone regs + slave_i => slave_i, + slave_o => slave_o, + start_recovery_o => start_recovery, + cpu_status_i => state_cpu_3 & state_cpu_2 & state_cpu_1, + boot_done_o => boot_done_o + + ); + + + + +end architecture; \ No newline at end of file diff --git a/hdl/wb_apb_adapter.vhd b/hdl/wb_apb_adapter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..5f1e3ac1357c3bbbf0571b42b3863d73f5f9f0d6 --- /dev/null +++ b/hdl/wb_apb_adapter.vhd @@ -0,0 +1,111 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +--library smartfusion2; +--use smartfusion2.all; + + +entity wb_apb_adapter is + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + arm_psel_i : in std_logic; + arm_pwr_i : in std_logic; + arm_pen_i : in std_logic; + arm_paddr_i : in std_logic_vector(31 downto 0); + arm_pwdat_i : in std_logic_vector(31 downto 0); + arm_prdat_o : out std_logic_vector(31 downto 0); + arm_pready_o : out std_logic; -- + + + --wishbone master + m_wb_adr_o : out std_logic_vector (31 downto 0); + m_wb_sel_o : out std_logic_vector (3 downto 0); + m_wb_we_o : out std_logic; + m_wb_dat_o : out std_logic_vector (31 downto 0); + m_wb_dat_i : in std_logic_vector (31 downto 0); + m_wb_cyc_o : out std_logic; + m_wb_stb_o : out std_logic; + m_wb_ack_i : in std_logic + + + ); +end entity wb_apb_adapter; + + +architecture rtl of wb_apb_adapter is + +signal addr_scrubber : unsigned (12 downto 0); +signal arm_pready : std_logic; + +type fsm_states is (idle, process_arm_apb); +signal fsm : fsm_states := idle; + + +attribute syn_encoding : string; +attribute syn_encoding of fsm : signal is "safe,onehot"; + + attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + + +begin + + + +m_wb_sel_o <= (others=>'1'); +arm_pready_o <= arm_pready; + +process (clk_i) +begin +if rst_i = '1' then +fsm <= idle; +arm_pready <= '0'; +addr_scrubber <= (others => '0'); +m_wb_we_o <= '0'; +m_wb_cyc_o <= '0'; +m_wb_stb_o <= '0'; +elsif rising_edge(clk_i) then + + case (fsm) is + when idle => + m_wb_cyc_o <= '0'; + m_wb_stb_o <= '0'; + arm_pready <= '0'; + if (arm_psel_i = '1' and arm_pen_i = '1' and arm_pready = '0') then + m_wb_cyc_o <= '1'; + m_wb_stb_o <= '1'; + m_wb_we_o <= arm_pwr_i; + --temp + m_wb_adr_o <= x"8500" & arm_paddr_i (15 downto 0); + m_wb_dat_o <= arm_pwdat_i; +-- end temp + fsm <= process_arm_apb; + end if; + when process_arm_apb => + arm_pready <= m_wb_ack_i; + +arm_prdat_o <= m_wb_dat_i; + if (m_wb_ack_i = '1') then + fsm <= idle; + m_wb_cyc_o <= '0'; + m_wb_stb_o <= '0'; + end if; + + when others => + fsm <= idle; + end case; +end if; +end process; + + + + + +end architecture; \ No newline at end of file diff --git a/hdl/wb_envm.vhd b/hdl/wb_envm.vhd new file mode 100644 index 0000000000000000000000000000000000000000..67ad9c3b2465c62d0e7c0a74a44f96ab29a3d077 --- /dev/null +++ b/hdl/wb_envm.vhd @@ -0,0 +1,286 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.wishbone_pkg.all; + + +entity wb_envm is + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + rst_cpu_o : out std_logic; + + apb_psel_o : out std_logic; + apb_pwr_o : out std_logic; + apb_pen_o : out std_logic; + apb_paddr_o : out std_logic_vector(31 downto 0); + apb_pwdat_o : out std_logic_vector(31 downto 0); + apb_prdat_i : in std_logic_vector(31 downto 0); + apb_pready_i : in std_logic; -- + + -- to the Wishbone xbar + master_i : in t_wishbone_master_in; + master_o : out t_wishbone_master_out; + + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out + + ); +end entity wb_envm; + + +architecture rtl of wb_envm is + +constant bootloader_addr : std_logic_vector (31 downto 0) := x"60012000"; -- (bits from 11 to 0 must be 0) +constant bootloader_size : integer := 256; -- words (max 256) + +type fsm_apb_states is (idle, setup, accessing); +type fsm_envm_states is (idle, check_status, poll_bit, data); +type fsm_bootstrap_states is (cold_start, poll_bit, fetch_word, wait_apb, wait_wb, checksum, done); +type fsm_wb_master_states is (idle, wait_ack); + +signal apb_fsm : fsm_apb_states := idle; +signal envm_fsm : fsm_envm_states := idle; +signal bootstrap_fsm : fsm_bootstrap_states := cold_start; +signal wb_fsm : fsm_wb_master_states := idle; + +signal apb_addr, apb_addr_boot, apb_addr_wb, envm_addr, envm_data, apb_data, wb_data, wb_data_reg : std_logic_vector (31 downto 0); + +signal envm_read_req_p, apb_read_req, apb_read_req_boot, apb_read_req_wb, apb_read_ack : std_logic; +signal wb_write_req, wb_write_req_boot, wb_write_req_wb, wb_write_ack : std_logic; +signal wb_addr, wb_addr_boot, wb_addr_wb : std_logic_vector (16 downto 0); +signal counter : unsigned (9 downto 0); +begin + +apb_addr <= apb_addr_boot when (rst_cpu_o = '1') else apb_addr_wb; +apb_read_req <= apb_read_req_boot when (rst_cpu_o = '1') else apb_read_req_wb; + +process (clk_i) +begin +if rising_edge (clk_i) then + if rst_i = '1' then + rst_cpu_o <= '1'; + bootstrap_fsm <= cold_start; + wb_write_req_boot <= '0'; + else + case (bootstrap_fsm) is + when cold_start => + rst_cpu_o <= '1'; + bootstrap_fsm <= poll_bit; + counter <= (others => '0'); + wb_write_req_boot <= '0'; + apb_addr_boot <= x"60080120"; + apb_read_req_boot <= '1'; + when poll_bit => + apb_read_req_boot <= '0'; + if (apb_read_ack = '1') then + if (apb_data (0) = '1') then -- busy bit + bootstrap_fsm <= fetch_word; + else + apb_read_req_boot <= '1'; + end if; + end if; + when fetch_word => + apb_read_req_boot <= '1'; + apb_addr_boot (31 downto 12) <= bootloader_addr (31 downto 12); + apb_addr_boot (11 downto 2) <= std_logic_vector(counter); + apb_addr_boot (1 downto 0) <= (others => '0'); + bootstrap_fsm <= wait_apb; + when wait_apb => + apb_read_req_boot <= '0'; + if (apb_read_ack = '1') then + bootstrap_fsm <= wait_wb; + wb_write_req_boot <= '1'; + wb_addr_boot <= (others => '0'); + wb_addr_boot (11 downto 2) <= std_logic_vector(counter); + end if; + when wait_wb => + wb_write_req_boot <= '0'; + if (wb_write_ack = '1') then + if (counter >= to_unsigned(bootloader_size-4, counter'length)) then + bootstrap_fsm <= checksum; + else + bootstrap_fsm <= fetch_word; + counter <= counter + 1; + end if; + end if; + when checksum => + -- to be done + bootstrap_fsm <= done; + when done => + rst_cpu_o <= '0'; + when others => + bootstrap_fsm <= done; + end case; + end if; +end if; +end process; + +wb_addr <= wb_addr_boot when (rst_cpu_o = '1') else wb_addr_wb; +wb_write_req <= wb_write_req_boot when (rst_cpu_o = '1') else wb_write_req_wb; +wb_data <= apb_data when (rst_cpu_o = '1') else wb_data_reg; + + +process (clk_i) +begin +if rising_edge (clk_i) then + if rst_i = '1' then + wb_fsm <= idle; + master_o.cyc <= '0'; + master_o.stb <= '0'; + master_o.adr <= (others => '0'); + else + case (wb_fsm) is + when idle => + master_o.cyc <= '0'; + master_o.stb <= '0'; + wb_write_ack <= '0'; + if (wb_write_req = '1' and wb_write_ack = '0') then + wb_fsm <= wait_ack; + master_o.cyc <= '1'; + master_o.stb <= '1'; + master_o.we <= '1'; + master_o.sel <= "1111"; + master_o.adr (wb_addr'left downto 0) <= wb_addr; + master_o.dat <= wb_data; + end if; + when wait_ack => + if (master_i.ack = '1') then + master_o.cyc <= '0'; + master_o.stb <= '0'; + master_o.we <= '0'; + wb_write_ack <= '1'; + wb_fsm <= idle; + end if; + when others => + wb_fsm <= idle; + end case; + + + end if; +end if; +end process; + +process (clk_i) +begin +if rising_edge(clk_i) then + if rst_i = '1' then + apb_fsm <= idle; + apb_psel_o <= '0'; + apb_pen_o <= '0'; + apb_pwr_o <= '0'; + apb_read_ack <= '0'; + else + case (apb_fsm) is + when idle => + apb_read_ack <= '0'; + if (apb_read_req = '1' and apb_read_ack = '0') then + apb_fsm <= setup; + apb_psel_o <= '1'; + apb_paddr_o <= apb_addr; + end if; + when setup => + apb_pen_o <= '1'; + apb_fsm <= accessing; + when accessing => + if (apb_pready_i = '1') then + apb_data <= apb_prdat_i; + apb_fsm <= idle; + apb_pen_o <= '0'; + apb_psel_o <= '0'; + apb_read_ack <= '1'; + end if; + when others => + apb_fsm <= idle; + end case; + end if; +end if; +end process; + +process (clk_i) +begin +if rising_edge (clk_i) then + if rst_i = '1' then + envm_fsm <= idle; + apb_read_req_wb <= '0'; + else + case (envm_fsm) is + when idle => + if (envm_read_req_p = '1') then + envm_fsm <= check_status; + end if; + when check_status => + if (apb_fsm = idle) then + apb_addr_wb <= x"60080120"; + apb_read_req_wb <= '1'; + envm_fsm <= poll_bit; + end if; + when poll_bit => + apb_read_req_wb <= '0'; + if (apb_read_ack = '1') then + if (apb_data (0) = '1') then -- busy bit + envm_fsm <= data; + apb_addr_wb <= envm_addr; + apb_read_req_wb <= '1'; + else + apb_read_req_wb <= '1'; -- retry + end if; + end if; + when data => + apb_read_req_wb <= '0'; + if (apb_read_ack = '1') then + envm_data <= apb_data; + envm_fsm <= idle; + end if; + when others => + envm_fsm <= idle; + end case; +end if; +end if; +end process; + +process (clk_i) +begin +if rising_edge (clk_i) then + envm_read_req_p <= '0'; + wb_write_req_wb <= '0'; + slave_o.ack <= '0'; + if (slave_i.stb = '1' and slave_i.cyc = '1' and slave_o.ack = '0') then + slave_o.ack <= '1'; + if (slave_i.adr(4 downto 2) = "000") then + slave_o.dat (31 downto 1) <= (others => '0'); + slave_o.dat (0) <= '1' when envm_fsm /= idle else '0'; + elsif (slave_i.adr (4 downto 2) = "001") then + slave_o.dat <= slave_i.dat; + if (slave_i.we = '1') then + envm_addr <= slave_i.dat; + envm_read_req_p <= '1'; + end if; + elsif (slave_i.adr (4 downto 2) = "010") then + slave_o.dat <= envm_data; + elsif (slave_i.adr (4 downto 2) = "100") then + slave_o.dat <= slave_i.dat; + if (slave_i.we = '1') then + wb_addr_wb <= slave_i.dat (wb_addr_wb'left downto 0); + end if; + elsif (slave_i.adr (4 downto 2) = "101") then + slave_o.dat <= slave_i.dat; + if (slave_i.we = '1') then + wb_data_reg <= slave_i.dat; + wb_write_req_wb <= '1'; + end if; + end if; + end if; +end if; +end process; + + + + + + + +end architecture; \ No newline at end of file diff --git a/hdl/wb_master_voter.vhd b/hdl/wb_master_voter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..6599f6ebb57c8b5422f5f6f4db926acb4ab01e61 --- /dev/null +++ b/hdl/wb_master_voter.vhd @@ -0,0 +1,65 @@ + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +library work; +use work.wishbone_pkg.all; + + + +package wb_master_voter_pkg is + type t_voter_wb_master is array (1 to 3) of t_wishbone_master_out; +end package; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +library work; +use work.wishbone_pkg.all; + +use work.wb_master_voter_pkg.all; + + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + + + +entity wb_master_voter is + + port ( + m_wb_i : in t_voter_wb_master; + m_wb_o : out t_wishbone_master_out + ); +end wb_master_voter; + +architecture rtl of wb_master_voter is + +begin + + m_wb_o.cyc <= (m_wb_i(1).cyc and m_wb_i(2).cyc) or (m_wb_i(2).cyc and m_wb_i(3).cyc) or (m_wb_i(1).cyc and m_wb_i(3).cyc); + m_wb_o.stb <= (m_wb_i(1).stb and m_wb_i(2).stb) or (m_wb_i(2).stb and m_wb_i(3).stb) or (m_wb_i(1).stb and m_wb_i(3).stb); + m_wb_o.we <= (m_wb_i(1).we and m_wb_i(2).we ) or (m_wb_i(2).we and m_wb_i(3).we ) or (m_wb_i(1).we and m_wb_i(3).we ); + + adr : for i in m_wb_o.adr'range generate + m_wb_o.adr(i) <= (m_wb_i(1).adr(i) and m_wb_i(2).adr(i)) or (m_wb_i(2).adr(i) and m_wb_i(3).adr(i)) or (m_wb_i(1).adr(i) and m_wb_i(3).adr(i)); + end generate; + + + sel : for i in m_wb_o.sel'range generate + m_wb_o.sel(i) <= (m_wb_i(1).sel(i) and m_wb_i(2).sel(i)) or (m_wb_i(2).sel(i) and m_wb_i(3).sel(i)) or (m_wb_i(1).sel(i) and m_wb_i(3).sel(i)); + end generate; + + + dat: for i in m_wb_o.dat'range generate + m_wb_o.dat(i) <= (m_wb_i(1).dat(i) and m_wb_i(2).dat(i)) or (m_wb_i(2).dat(i) and m_wb_i(3).dat(i)) or (m_wb_i(1).dat(i) and m_wb_i(3).dat(i)); + end generate; + + + end architecture; diff --git a/hdl/wb_ram_scrubber.vhdl b/hdl/wb_ram_scrubber.vhdl new file mode 100644 index 0000000000000000000000000000000000000000..8331e22b5c569926314b4a951b97b40a159d6731 --- /dev/null +++ b/hdl/wb_ram_scrubber.vhdl @@ -0,0 +1,154 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +--library smartfusion2; +--use smartfusion2.all; + + +entity wb_ram_scrubber is + + port ( + clk_i : in std_logic; + rst_i : in std_logic; + cpu_status_i : in std_logic; + -- Wishbone + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + + -- ram interface + addr_o : out std_logic_vector(14 downto 0); + data_o : out std_logic_vector(31 downto 0); + data_i : in std_logic_vector(31 downto 0); + wen_o : out std_logic; + ren_o : out std_logic; + done_i : in std_logic + + ); +end entity wb_ram_scrubber; + + +architecture rtl of wb_ram_scrubber is + +signal addr_scrubber : unsigned (14 downto 0); +signal pwr, wr : std_logic; + +type fsm_states is (idle, process_wb, scrubber_read, process_wb_partial_write, process_wb_write); +signal fsm : fsm_states := idle; + + +attribute syn_encoding : string; +attribute syn_encoding of fsm : signal is "safe,onehot"; + +--attribute syn_radhardlevel : string; +--attribute syn_radhardlevel of pwr : signal is "tmr"; +--attribute syn_radhardlevel of wr : signal is "tmr"; + + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + +signal ack: std_logic; + +signal data_read : std_logic_vector (31 downto 0); + +function f_mask_word (mask : std_logic_vector (3 downto 0); d1 : std_logic_vector (31 downto 0); d2 : std_logic_vector (31 downto 0)) return std_logic_vector is +variable masked_word : std_logic_vector (31 downto 0); +begin +for i in 1 to 4 loop +if (mask(i-1) = '0') then + masked_word (i*8-1 downto (i-1)*8) := d2(i*8-1 downto (i-1)*8); +else + masked_word (i*8-1 downto (i-1)*8) := d1(i*8-1 downto (i-1)*8); +end if; +end loop; +return masked_word; +end f_mask_word; + +begin + +slave_o.ack <= ack; + +--slave_o.stall <= '0' when slave_i.cyc = '0' else not ack; +slave_o.stall <= (not ack) and slave_i.cyc and slave_i.stb; + +process (clk_i) +begin +if rst_i = '1' then +fsm <= idle; +addr_scrubber <= (others => '0'); +wen_o <= '0'; +ren_o <= '0'; +ack <= '0'; +elsif rising_edge(clk_i) then + + case (fsm) is + when idle => + wen_o <= '0'; + ren_o <= '0'; + ack <= '0'; + if (slave_i.stb = '1' and slave_i.cyc = '1' and ack = '0') then + fsm <= process_wb; + if (slave_i.we = '1' and slave_i.sel = "1111") then + wen_o <= '1'; + ren_o <= '0'; + data_o <= slave_i.dat; + else + ren_o <= '1'; + wen_o <= '0'; + end if; + addr_o <= slave_i.adr (14 downto 0); + + end if; + when process_wb => + wen_o <= '0'; + ren_o <= '0'; + slave_o.dat <= data_i; + + if (done_i = '1') then + if (slave_i.we = '1' and slave_i.sel /= "1111") then + fsm <= process_wb_partial_write; + data_read <= data_i; + else + fsm <= idle; + ack <= '1'; + end if; + end if; + when process_wb_partial_write => + data_o <= f_mask_word(slave_i.sel, slave_i.dat, data_read); + wen_o <= '1'; + ren_o <= '0'; + fsm <= process_wb_write; + when process_wb_write => + wen_o <= '0'; + ren_o <= '0'; + if (done_i = '1') then + fsm <= idle; + ack <= '1'; + end if; + + + + when scrubber_read => + ren_o <= '0'; + if (done_i = '1') then + fsm <= idle; + addr_scrubber <= addr_scrubber + 4; + end if; + when others => + fsm <= idle; + end case; +end if; +end process; + + + + + +end architecture; \ No newline at end of file diff --git a/hdl/wb_seu_reg.vhdl b/hdl/wb_seu_reg.vhdl new file mode 100644 index 0000000000000000000000000000000000000000..00ae4b3f38e0cf55c9f8250c28b4408acf476256 --- /dev/null +++ b/hdl/wb_seu_reg.vhdl @@ -0,0 +1,105 @@ +--------------------------------------------------------------------------------------- +-- Title : Wishbone slave core for seu ram counter +--------------------------------------------------------------------------------------- +-- File : wb_seu_reg.vhdl +-- Author : auto-generated by wbgen2 from SEU.wb +-- Created : 11/20/18 14:56:41 +-- Standard : VHDL'87 +--------------------------------------------------------------------------------------- +-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE SEU.wb +-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY! +--------------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity wb_seu_regs is + port ( + rst_n_i : in std_logic; + clk_sys_i : in std_logic; + wb_dat_i : in std_logic_vector(31 downto 0); + wb_dat_o : out std_logic_vector(31 downto 0); + wb_cyc_i : in std_logic; + wb_sel_i : in std_logic_vector(3 downto 0); + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_err_o : out std_logic; + wb_rty_o : out std_logic; + wb_stall_o : out std_logic; + wb_adr_i : in std_logic_vector(4 downto 0); +-- Port for std_logic_vector field: 'Single errors' in reg: 'counter values' + iram_seu_regs_see_se_i : in std_logic_vector(15 downto 0); +-- Port for std_logic_vector field: 'Double errors' in reg: 'counter values' + iram_seu_regs_see_de_i : in std_logic_vector(15 downto 0); + -- Port for std_logic_vector field: 'Single errors' in reg: 'counter values' + dram_seu_regs_see_se_i : in std_logic_vector(15 downto 0); +-- Port for std_logic_vector field: 'Double errors' in reg: 'counter values' + dram_seu_regs_see_de_i : in std_logic_vector(15 downto 0) + ); +end wb_seu_regs; + +architecture syn of wb_seu_regs is + +signal ack_sreg : std_logic_vector(9 downto 0); +signal rddata_reg : std_logic_vector(31 downto 0); +signal wrdata_reg : std_logic_vector(31 downto 0); +signal bwsel_reg : std_logic_vector(3 downto 0); +signal rwaddr_reg : std_logic_vector(0 downto 0); +signal ack_in_progress : std_logic ; +signal wr_int : std_logic ; +signal rd_int : std_logic ; +signal allones : std_logic_vector(31 downto 0); +signal allzeros : std_logic_vector(31 downto 0); + +begin +-- Some internal signals assignments + wrdata_reg <= wb_dat_i; +-- +-- Main register bank access process. + process (clk_sys_i, rst_n_i) + begin + if (rst_n_i = '0') then + ack_sreg <= "0000000000"; + ack_in_progress <= '0'; + rddata_reg <= "00000000000000000000000000000000"; + elsif rising_edge(clk_sys_i) then +-- advance the ACK generator shift register + ack_sreg(8 downto 0) <= ack_sreg(9 downto 1); + ack_sreg(9) <= '0'; + if (ack_in_progress = '1') then + if (ack_sreg(0) = '1') then + ack_in_progress <= '0'; + else + end if; + else + if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then + if (wb_we_i = '1') then + end if; + if (wb_adr_i (2) = '0') then + rddata_reg(15 downto 0) <= iram_seu_regs_see_se_i; + rddata_reg(31 downto 16) <= iram_seu_regs_see_de_i; + else + rddata_reg(15 downto 0) <= dram_seu_regs_see_se_i; + rddata_reg(31 downto 16) <= dram_seu_regs_see_de_i; + end if; + ack_sreg(0) <= '1'; + ack_in_progress <= '1'; + end if; + end if; + end if; + end process; + + +-- Drive the data output bus + wb_dat_o <= rddata_reg; +-- Single errors +-- Double errors + rwaddr_reg <= (others => '0'); + wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i); + wb_err_o <= '0'; + wb_rty_o <= '0'; +-- ACK signal generation. Just pass the LSB of ACK counter. + wb_ack_o <= ack_sreg(0); +end syn; diff --git a/hdl/wb_slave_voter.vhd b/hdl/wb_slave_voter.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1201953a20c04aebf2cee253cea68a25bed604bd --- /dev/null +++ b/hdl/wb_slave_voter.vhd @@ -0,0 +1,59 @@ + + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +library work; +use work.wishbone_pkg.all; + + + +package wb_slave_voter_pkg is + type t_voter_wb_slave is array (1 to 3) of t_wishbone_slave_out; +end package; + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + + +library work; +use work.wishbone_pkg.all; + +use work.wb_slave_voter_pkg.all; + + +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + + + +entity wb_slave_voter is + + port ( + s_wb_i : in t_voter_wb_slave; + s_wb_o : out t_wishbone_slave_out + ); +end wb_slave_voter; + +architecture rtl of wb_slave_voter is + +begin + + s_wb_o.ack <= (s_wb_i(1).ack and s_wb_i(2).ack) or (s_wb_i(2).ack and s_wb_i(3).ack) or (s_wb_i(1).ack and s_wb_i(3).ack); + s_wb_o.stall <= (s_wb_i(1).stall and s_wb_i(2).stall) or (s_wb_i(2).stall and s_wb_i(3).stall) or (s_wb_i(1).stall and s_wb_i(3).stall); + + + + dat : for i in s_wb_o.dat'range generate + s_wb_o.dat(i) <= (s_wb_i(1).dat(i) and s_wb_i(2).dat(i)) or (s_wb_i(2).dat(i) and s_wb_i(3).dat(i)) or (s_wb_i(1).dat(i) and s_wb_i(3).dat(i)); + end generate; + + + + + + end architecture; diff --git a/hdl/wb_uart.vhdl b/hdl/wb_uart.vhdl new file mode 100644 index 0000000000000000000000000000000000000000..5c50d9ebae3fd5f98acf28f723d74c69be8d7636 --- /dev/null +++ b/hdl/wb_uart.vhdl @@ -0,0 +1,190 @@ +--------------------------------------------------------------------------------------- +-- Title : Wishbone slave core for Simple Wishbone UART +--------------------------------------------------------------------------------------- +-- File : wb_uart.vhdl +-- Author : auto-generated by wbgen2 from uart.wb +-- Created : 11/22/18 12:43:29 +-- Standard : VHDL'87 +--------------------------------------------------------------------------------------- +-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE uart.wb +-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY! +--------------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity wb_uart is + port ( + rst_n_i : in std_logic; + clk_sys_i : in std_logic; + wb_adr_i : in std_logic_vector(0 downto 0); + wb_dat_i : in std_logic_vector(31 downto 0); + wb_dat_o : out std_logic_vector(31 downto 0); + wb_cyc_i : in std_logic; + wb_sel_i : in std_logic_vector(3 downto 0); + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_err_o : out std_logic; + wb_rty_o : out std_logic; + wb_stall_o : out std_logic; +-- Port for BIT field: 'TX busy' in reg: 'Status Register' + uart_sr_tx_busy_i : in std_logic; +-- Port for MONOSTABLE field: 'TX trigger' in reg: 'Status Register' + uart_sr_tx_send_o : out std_logic; +-- Port for std_logic_vector field: 'Transmit data' in reg: 'Transmit data register' + uart_tdr_tx_data_o : out std_logic_vector(7 downto 0) + ); +end wb_uart; + +architecture syn of wb_uart is + +signal uart_sr_tx_send_dly0 : std_logic ; +signal uart_sr_tx_send_int : std_logic ; +signal uart_tdr_tx_data_int : std_logic_vector(7 downto 0); +signal ack_sreg : std_logic_vector(9 downto 0); +signal rddata_reg : std_logic_vector(31 downto 0); +signal wrdata_reg : std_logic_vector(31 downto 0); +signal bwsel_reg : std_logic_vector(3 downto 0); +signal rwaddr_reg : std_logic_vector(0 downto 0); +signal ack_in_progress : std_logic ; +signal wr_int : std_logic ; +signal rd_int : std_logic ; +signal allones : std_logic_vector(31 downto 0); +signal allzeros : std_logic_vector(31 downto 0); + + attribute syn_radhardlevel : string; +attribute syn_radhardlevel of syn : architecture is "tmr"; + +begin +-- Some internal signals assignments + wrdata_reg <= wb_dat_i; +-- +-- Main register bank access process. + process (clk_sys_i, rst_n_i) + begin + if (rst_n_i = '0') then + ack_sreg <= "0000000000"; + ack_in_progress <= '0'; + rddata_reg <= "00000000000000000000000000000000"; + uart_sr_tx_send_int <= '0'; + uart_tdr_tx_data_int <= "00000000"; + elsif rising_edge(clk_sys_i) then +-- advance the ACK generator shift register + ack_sreg(8 downto 0) <= ack_sreg(9 downto 1); + ack_sreg(9) <= '0'; + if (ack_in_progress = '1') then + if (ack_sreg(0) = '1') then + uart_sr_tx_send_int <= '0'; + ack_in_progress <= '0'; + else + end if; + else + if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then + case rwaddr_reg(0) is + when '0' => + if (wb_we_i = '1') then + uart_sr_tx_send_int <= wrdata_reg(1); + end if; + rddata_reg(0) <= uart_sr_tx_busy_i; + rddata_reg(1) <= '0'; + rddata_reg(2) <= '0'; + rddata_reg(3) <= '0'; + rddata_reg(4) <= '0'; + rddata_reg(5) <= '0'; + rddata_reg(6) <= '0'; + rddata_reg(7) <= '0'; + rddata_reg(8) <= '0'; + rddata_reg(9) <= '0'; + rddata_reg(10) <= '0'; + rddata_reg(11) <= '0'; + rddata_reg(12) <= '0'; + rddata_reg(13) <= '0'; + rddata_reg(14) <= '0'; + rddata_reg(15) <= '0'; + rddata_reg(16) <= '0'; + rddata_reg(17) <= '0'; + rddata_reg(18) <= '0'; + rddata_reg(19) <= '0'; + rddata_reg(20) <= '0'; + rddata_reg(21) <= '0'; + rddata_reg(22) <= '0'; + rddata_reg(23) <= '0'; + rddata_reg(24) <= '0'; + rddata_reg(25) <= '0'; + rddata_reg(26) <= '0'; + rddata_reg(27) <= '0'; + rddata_reg(28) <= '0'; + rddata_reg(29) <= '0'; + rddata_reg(30) <= '0'; + rddata_reg(31) <= '0'; + ack_sreg(2) <= '1'; + ack_in_progress <= '1'; + when '1' => + if (wb_we_i = '1') then + uart_tdr_tx_data_int <= wrdata_reg(7 downto 0); + end if; + rddata_reg(7 downto 0) <= uart_tdr_tx_data_int; + rddata_reg(8) <= 'X'; + rddata_reg(9) <= 'X'; + rddata_reg(10) <= 'X'; + rddata_reg(11) <= 'X'; + rddata_reg(12) <= 'X'; + rddata_reg(13) <= 'X'; + rddata_reg(14) <= 'X'; + rddata_reg(15) <= 'X'; + rddata_reg(16) <= 'X'; + rddata_reg(17) <= 'X'; + rddata_reg(18) <= 'X'; + rddata_reg(19) <= 'X'; + rddata_reg(20) <= 'X'; + rddata_reg(21) <= 'X'; + rddata_reg(22) <= 'X'; + rddata_reg(23) <= 'X'; + rddata_reg(24) <= 'X'; + rddata_reg(25) <= 'X'; + rddata_reg(26) <= 'X'; + rddata_reg(27) <= 'X'; + rddata_reg(28) <= 'X'; + rddata_reg(29) <= 'X'; + rddata_reg(30) <= 'X'; + rddata_reg(31) <= 'X'; + ack_sreg(0) <= '1'; + ack_in_progress <= '1'; + when others => +-- prevent the slave from hanging the bus on invalid address + ack_in_progress <= '1'; + ack_sreg(0) <= '1'; + end case; + end if; + end if; + end if; + end process; + + +-- Drive the data output bus + wb_dat_o <= rddata_reg; +-- TX busy +-- TX trigger + process (clk_sys_i, rst_n_i) + begin + if (rst_n_i = '0') then + uart_sr_tx_send_dly0 <= '0'; + uart_sr_tx_send_o <= '0'; + elsif rising_edge(clk_sys_i) then + uart_sr_tx_send_dly0 <= uart_sr_tx_send_int; + uart_sr_tx_send_o <= uart_sr_tx_send_int and (not uart_sr_tx_send_dly0); + end if; + end process; + + +-- Transmit data + uart_tdr_tx_data_o <= uart_tdr_tx_data_int; + rwaddr_reg <= wb_adr_i; + wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i); + wb_err_o <= '0'; + wb_rty_o <= '0'; +-- ACK signal generation. Just pass the LSB of ACK counter. + wb_ack_o <= ack_sreg(0); +end syn; diff --git a/hdl/wb_wd_reg.vhdl b/hdl/wb_wd_reg.vhdl new file mode 100644 index 0000000000000000000000000000000000000000..aabcba51c93a5ee93c965bd9be53a8a220dbb86c --- /dev/null +++ b/hdl/wb_wd_reg.vhdl @@ -0,0 +1,141 @@ +--------------------------------------------------------------------------------------- +-- Title : Wishbone slave core for Watchdog +--------------------------------------------------------------------------------------- +-- File : wb_wd_reg.vhdl +-- Author : auto-generated by wbgen2 from wd.wb +-- Created : 11/20/18 16:06:29 +-- Standard : VHDL'87 +--------------------------------------------------------------------------------------- +-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wd.wb +-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY! +--------------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity wd_regs is + port ( + rst_n_i : in std_logic; + clk_sys_i : in std_logic; + wb_dat_i : in std_logic_vector(31 downto 0); + wb_dat_o : out std_logic_vector(31 downto 0); + wb_cyc_i : in std_logic; + wb_sel_i : in std_logic_vector(3 downto 0); + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_err_o : out std_logic; + wb_rty_o : out std_logic; + wb_stall_o : out std_logic; +-- Port for MONOSTABLE field: 'Heartbeat' in reg: 'Watchdog' + wd_reg_heartbeat_o : out std_logic + ); +end wd_regs; + +architecture syn of wd_regs is + +signal wd_reg_heartbeat_dly0 : std_logic ; +signal wd_reg_heartbeat_int : std_logic ; +signal ack_sreg : std_logic_vector(9 downto 0); +signal rddata_reg : std_logic_vector(31 downto 0); +signal wrdata_reg : std_logic_vector(31 downto 0); +signal bwsel_reg : std_logic_vector(3 downto 0); +signal rwaddr_reg : std_logic_vector(0 downto 0); +signal ack_in_progress : std_logic ; +signal wr_int : std_logic ; +signal rd_int : std_logic ; +signal allones : std_logic_vector(31 downto 0); +signal allzeros : std_logic_vector(31 downto 0); + +begin +-- Some internal signals assignments + wrdata_reg <= wb_dat_i; +-- +-- Main register bank access process. + process (clk_sys_i, rst_n_i) + begin + if (rst_n_i = '0') then + ack_sreg <= "0000000000"; + ack_in_progress <= '0'; + rddata_reg <= "00000000000000000000000000000000"; + wd_reg_heartbeat_int <= '0'; + elsif rising_edge(clk_sys_i) then +-- advance the ACK generator shift register + ack_sreg(8 downto 0) <= ack_sreg(9 downto 1); + ack_sreg(9) <= '0'; + if (ack_in_progress = '1') then + if (ack_sreg(0) = '1') then + wd_reg_heartbeat_int <= '0'; + ack_in_progress <= '0'; + else + end if; + else + if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then + if (wb_we_i = '1') then + wd_reg_heartbeat_int <= wrdata_reg(0); + end if; + rddata_reg(0) <= '0'; + rddata_reg(0) <= 'X'; + rddata_reg(1) <= 'X'; + rddata_reg(2) <= 'X'; + rddata_reg(3) <= 'X'; + rddata_reg(4) <= 'X'; + rddata_reg(5) <= 'X'; + rddata_reg(6) <= 'X'; + rddata_reg(7) <= 'X'; + rddata_reg(8) <= 'X'; + rddata_reg(9) <= 'X'; + rddata_reg(10) <= 'X'; + rddata_reg(11) <= 'X'; + rddata_reg(12) <= 'X'; + rddata_reg(13) <= 'X'; + rddata_reg(14) <= 'X'; + rddata_reg(15) <= 'X'; + rddata_reg(16) <= 'X'; + rddata_reg(17) <= 'X'; + rddata_reg(18) <= 'X'; + rddata_reg(19) <= 'X'; + rddata_reg(20) <= 'X'; + rddata_reg(21) <= 'X'; + rddata_reg(22) <= 'X'; + rddata_reg(23) <= 'X'; + rddata_reg(24) <= 'X'; + rddata_reg(25) <= 'X'; + rddata_reg(26) <= 'X'; + rddata_reg(27) <= 'X'; + rddata_reg(28) <= 'X'; + rddata_reg(29) <= 'X'; + rddata_reg(30) <= 'X'; + rddata_reg(31) <= 'X'; + ack_sreg(2) <= '1'; + ack_in_progress <= '1'; + end if; + end if; + end if; + end process; + + +-- Drive the data output bus + wb_dat_o <= rddata_reg; +-- Heartbeat + process (clk_sys_i, rst_n_i) + begin + if (rst_n_i = '0') then + wd_reg_heartbeat_dly0 <= '0'; + wd_reg_heartbeat_o <= '0'; + elsif rising_edge(clk_sys_i) then + wd_reg_heartbeat_dly0 <= wd_reg_heartbeat_int; + wd_reg_heartbeat_o <= wd_reg_heartbeat_int and (not wd_reg_heartbeat_dly0); + end if; + end process; + + + rwaddr_reg <= (others => '0'); + wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i); + wb_err_o <= '0'; + wb_rty_o <= '0'; + +-- ACK signal generation. Just pass the LSB of ACK counter. + wb_ack_o <= ack_sreg(0); +end syn; diff --git a/hdl/xwb_ram_adapter.vhdl b/hdl/xwb_ram_adapter.vhdl new file mode 100644 index 0000000000000000000000000000000000000000..2651baf73ed6275c5c204c0bea6360047f0b4f1b --- /dev/null +++ b/hdl/xwb_ram_adapter.vhdl @@ -0,0 +1,322 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +--library synplify; +--use synplify.attributes.all; +--use synplify.all; + +library work; +use work.wishbone_pkg.all; +--library smartfusion2; +--use smartfusion2.all; + + +entity xwb_ram_adapter is + generic ( + g_addr_width : natural := 15; + g_data_width :natural := 39; + g_is_iram : boolean := false; + g_is_dram : boolean := false + + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + boot_done_i : in std_logic; + + -- Wishbone + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + + -- ram interface + d_ram_i : in std_logic_vector (g_data_width-1 downto 0); + q_ram_o : out std_logic_vector (g_data_width-1 downto 0); + a_ram_o : out std_logic_vector (g_addr_width-1 downto 0); + we_ram_o : out std_logic; + re_ram_o : out std_logic; + valid_ram_i : in std_logic; + lock_req_o : out std_logic; + lock_grant_i : in std_logic; + + single_error_p_o : out std_logic; + double_error_p_o : out std_logic + + ); +end entity xwb_ram_adapter; + + +architecture rtl of xwb_ram_adapter is + + component secded_ecc is + generic ( + g_addr_width : natural := 15 + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + + -- to the processor/bus + d_i : in std_logic_vector(31 downto 0); + a_i : in std_logic_vector(g_addr_width-1 downto 0); + we_i : in std_logic; + bwe_i : in std_logic_vector (3 downto 0); + re_i : in std_logic; + + q_o : out std_logic_vector(31 downto 0); + done_r_o : out std_logic; + done_w_o : out std_logic; + + --to the BRAM + d_ram_i : in std_logic_vector (38 downto 0); + q_ram_o : out std_logic_vector (38 downto 0); + a_ram_o : out std_logic_vector (g_addr_width-1 downto 0); + we_ram_o : out std_logic; + re_ram_o : out std_logic; + valid_ram_i : in std_logic; + lock_req_o : out std_logic; + lock_grant_i : in std_logic; + + single_error_p_o : out std_logic; + double_error_p_o : out std_logic; + read_fault_p_o : out std_logic; + write_fault_p_o : out std_logic + ); + + + end component; + + component secded_ecc_daec is + generic ( + g_addr_width : natural := 15 + ); + port ( + clk_i : in std_logic; + rst_i : in std_logic; + + + -- to the processor/bus + d_i : in std_logic_vector(31 downto 0); + a_i : in std_logic_vector(g_addr_width-1 downto 0); + we_i : in std_logic; + bwe_i : in std_logic_vector (3 downto 0); + re_i : in std_logic; + + q_o : out std_logic_vector(31 downto 0); + done_r_o : out std_logic; + done_w_o : out std_logic; + + --to the BRAM + d_ram_i : in std_logic_vector (41 downto 0); + q_ram_o : out std_logic_vector (41 downto 0); + a_ram_o : out std_logic_vector (g_addr_width-1 downto 0); + we_ram_o : out std_logic; + re_ram_o : out std_logic; + valid_ram_i : in std_logic; + lock_req_o : out std_logic; + lock_grant_i : in std_logic; + + single_error_p_o : out std_logic; + double_error_p_o : out std_logic; + read_fault_p_o : out std_logic; + write_fault_p_o : out std_logic + ); + + + end component; + + + signal addr_scrubber : unsigned (15 downto 0); + signal timeout_wb : unsigned (3 downto 0); + signal pwr, wr : std_logic; + + type fsm_states is (idle, process_wb, scrubber_read); + signal fsm : fsm_states := idle; + + signal we, re : std_logic; + signal addr : std_logic_vector (g_addr_width-1 downto 0); + signal data_in, data_out : std_logic_vector (31 downto 0); +signal bwe : std_logic_vector (3 downto 0); + + attribute syn_radhardlevel : string; + attribute syn_radhardlevel of rtl : architecture is "tmr"; + + + signal ack, done_r, done_w : std_logic; + + signal data_read : std_logic_vector (31 downto 0); + +attribute syn_encoding : string; +attribute syn_encoding of fsm : signal is "safe,onehot"; + + +begin + + + slave_o.ack <= ack; + slave_o.stall <= (not ack) and slave_i.cyc and slave_i.stb; + slave_o.err <= '0'; + slave_o.int <= '0'; + slave_o.rty <= '0'; + process (clk_i) + begin + + if rising_edge (clk_i) then + if rst_i = '1' then + fsm <= idle; + addr_scrubber <= (x"0000"); + we <= '0'; + re <= '0'; + ack <= '0'; + timeout_wb <= (others => '0'); + addr <= (others => '0'); + else + + if (timeout_wb /= (timeout_wb'range => '1')) then + timeout_wb <= timeout_wb + 1; + end if; + + case (fsm) is + when idle => + we <= '0'; + re <= '0'; + ack <= '0'; + if (slave_i.stb = '1' and slave_i.cyc = '1' and ack = '0') then + fsm <= process_wb; + we <= slave_i.we; + + if boot_done_i = '0' then + we <= slave_i.we; + elsif (g_is_iram and slave_i.we = '1') then + we <= '0'; + fsm <= idle; + report "Attempt to write iram in runtime" severity error; + elsif (g_is_dram and slave_i.we = '1') then + if (g_addr_width = 15 and slave_i.adr (g_addr_width-1 downto g_addr_width-3) /= "111") then + we <= '0'; + fsm <= idle; + report "Attempt to write lower part of dram in runtime" severity error; + end if; + + if (g_addr_width = 16 and slave_i.adr (g_addr_width-1 downto g_addr_width-4) /= "1111") then + we <= '0'; + fsm <= idle; + report "Attempt to write lower part of dram in runtime" severity error; + end if; + end if; + bwe <= slave_i.sel; + re <= not slave_i.we; + data_in <= slave_i.dat; + addr <= slave_i.adr (g_addr_width-1 downto 0); + elsif (boot_done_i = '1' and timeout_wb = (timeout_wb'range => '1')) then + fsm <= scrubber_read; + re <= '1'; + addr <= std_logic_vector(addr_scrubber(g_addr_width-1 downto 0)); + end if; + when process_wb => + + slave_o.dat <= data_out; + + if ((re = '1' and done_r = '1') or (we = '1' and done_w = '1')) then + re <= '0'; + we <= '0'; + fsm <= idle; + ack <= '1'; + timeout_wb <= (others => '0'); + end if; + + + when scrubber_read => + + if (done_r = '1') then + re <= '0'; + fsm <= idle; + addr_scrubber <= addr_scrubber+4; + end if; + when others => + fsm <= idle; + end case; + end if; +end if; + end process; + +ecc_simple : if g_data_width = 39 generate + ecc_circuitry : secded_ecc + generic map ( + g_addr_width => g_addr_width + ) + port map ( + clk_i => clk_i, + rst_i => rst_i, + + + d_i => data_in, + a_i => addr, + we_i => we and not done_w, + bwe_i => bwe, + re_i => re and not done_r, + + q_o => data_out, + done_r_o => done_r, + done_w_o => done_w, + + --to the BRAM + d_ram_i => d_ram_i, + q_ram_o => q_ram_o, + a_ram_o => a_ram_o, + we_ram_o => we_ram_o, + re_ram_o => re_ram_o, + valid_ram_i => valid_ram_i, + + lock_req_o => lock_req_o, + lock_grant_i => lock_grant_i, + + single_error_p_o => single_error_p_o, + double_error_p_o => double_error_p_o, + read_fault_p_o => open, + write_fault_p_o => open + ); +end generate ecc_simple; + +ecc_daec : if g_data_width = 42 generate + ecc_circuitry : secded_ecc_daec + generic map ( + g_addr_width => g_addr_width + ) + port map ( + clk_i => clk_i, + rst_i => rst_i, + + + d_i => data_in, + a_i => addr, + we_i => we and not done_w, + bwe_i => bwe, + re_i => re and not done_r, + + q_o => data_out, + done_r_o => done_r, + done_w_o => done_w, + + --to the BRAM + d_ram_i => d_ram_i, + q_ram_o => q_ram_o, + a_ram_o => a_ram_o, + we_ram_o => we_ram_o, + re_ram_o => re_ram_o, + valid_ram_i => valid_ram_i, + + lock_req_o => lock_req_o, + lock_grant_i => lock_grant_i, + + single_error_p_o => single_error_p_o, + double_error_p_o => double_error_p_o, + read_fault_p_o => open, + write_fault_p_o => open + ); + +end generate ecc_daec; + + +end architecture; \ No newline at end of file diff --git a/hdl/xwb_seu_reg.vhd b/hdl/xwb_seu_reg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..0d13842ceae7081f247e64fe5da0eff43a32ab87 --- /dev/null +++ b/hdl/xwb_seu_reg.vhd @@ -0,0 +1,96 @@ +library ieee; +use ieee.std_logic_1164.all; + +library work; +use work.wishbone_pkg.all; + +entity xwb_seu_regs is + + port( + clk_sys_i : in std_logic; + rst_i : in std_logic; + + -- Wishbone + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; + + iram_seu_regs_see_se_i : in std_logic_vector(15 downto 0); + iram_seu_regs_see_de_i : in std_logic_vector(15 downto 0); + dram_seu_regs_see_se_i : in std_logic_vector(15 downto 0); + dram_seu_regs_see_de_i : in std_logic_vector(15 downto 0) + ); + +end xwb_seu_regs; + +architecture rtl of xwb_seu_regs is + + + +component wb_seu_regs + port ( + rst_n_i : in std_logic; + clk_sys_i : in std_logic; + wb_dat_i : in std_logic_vector(31 downto 0); + wb_dat_o : out std_logic_vector(31 downto 0); + wb_cyc_i : in std_logic; + wb_sel_i : in std_logic_vector(3 downto 0); + wb_adr_i : in std_logic_vector(4 downto 0); + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_err_o : out std_logic; + wb_rty_o : out std_logic; + wb_stall_o : out std_logic; +-- Port for std_logic_vector field: 'Single errors' in reg: 'counter values' + iram_seu_regs_see_se_i : in std_logic_vector(15 downto 0); +-- Port for std_logic_vector field: 'Double errors' in reg: 'counter values' + iram_seu_regs_see_de_i : in std_logic_vector(15 downto 0); + -- Port for std_logic_vector field: 'Single errors' in reg: 'counter values' + dram_seu_regs_see_se_i : in std_logic_vector(15 downto 0); +-- Port for std_logic_vector field: 'Double errors' in reg: 'counter values' + dram_seu_regs_see_de_i : in std_logic_vector(15 downto 0) + ); +end component; + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + +begin + + + + + U_Wrapped_seu: wb_seu_regs + + port map ( + clk_sys_i => clk_sys_i, + rst_n_i => not rst_i, + wb_adr_i => slave_i.adr(4 downto 0), + wb_dat_i => slave_i.dat, + wb_dat_o => slave_o.dat, + wb_cyc_i => slave_i.cyc, + wb_sel_i => slave_i.sel, + wb_stb_i => slave_i.stb, + wb_we_i => slave_i.we, + wb_ack_o => slave_o.ack, + wb_stall_o => slave_o.stall, + iram_seu_regs_see_se_i => iram_seu_regs_see_se_i, + iram_seu_regs_see_de_i => iram_seu_regs_see_de_i, + dram_seu_regs_see_se_i => dram_seu_regs_see_se_i, + dram_seu_regs_see_de_i => dram_seu_regs_see_de_i + ); + + slave_o.err <= '0'; + slave_o.rty <= '0'; + slave_o.int <='0'; + + desc_o <= (others => '0'); + + + +end architecture; + + + + diff --git a/hdl/xwb_supervisor_reg.vhd b/hdl/xwb_supervisor_reg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..18147d650e5fe603fb2b948f1b2c3c3916e84b23 --- /dev/null +++ b/hdl/xwb_supervisor_reg.vhd @@ -0,0 +1,94 @@ + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.wishbone_pkg.all; + +entity xwb_supervisor_reg is + port ( + rst_i : in std_logic; + clk_sys_i : in std_logic; + + + -- Wishbone regs + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + start_recovery_o : out std_logic; + cpu_status_i : in std_logic_vector(2 downto 0); + boot_done_o : out std_logic + + ); +end xwb_supervisor_reg; + +architecture rtl of xwb_supervisor_reg is + + signal ack_sreg : std_logic_vector(9 downto 0); + signal rddata_reg : std_logic_vector(31 downto 0); + signal wrdata_reg : std_logic_vector(31 downto 0); + signal bwsel_reg : std_logic_vector(3 downto 0); + signal rwaddr_reg : std_logic_vector(0 downto 0); + signal ack_in_progress : std_logic; + signal wr_int : std_logic; + signal rd_int : std_logic; + signal allones : std_logic_vector(31 downto 0); + signal allzeros : std_logic_vector(31 downto 0); + + signal hot_boot : std_logic; + attribute syn_radhardlevel : string; + attribute syn_radhardlevel of rtl : architecture is "tmr"; + +begin + + + +-- Main register bank access process. + process (clk_sys_i, rst_i) + begin + if (rst_i = '1') then + ack_sreg <= "0000000000"; + ack_in_progress <= '0'; + rddata_reg <= "00000000000000000000000000000000"; + start_recovery_o <= '0'; + hot_boot <= '0'; + elsif rising_edge(clk_sys_i) then +-- advance the ACK generator shift register + ack_sreg(8 downto 0) <= ack_sreg(9 downto 1); + ack_sreg(9) <= '0'; + start_recovery_o <= '0'; + if (ack_in_progress = '1') then + if (ack_sreg(0) = '1') then + ack_in_progress <= '0'; + else + end if; + else + if ((slave_i.cyc = '1') and (slave_i.stb = '1')) then + if (slave_i.we = '1') then + start_recovery_o <= slave_i.dat(1); + if (slave_i.dat(0) = '1') then + hot_boot <= '1'; + end if; + + end if; + rddata_reg(0) <= hot_boot; + rddata_reg(15 downto 1) <= (others => '0'); + rddata_reg(18 downto 16) <= cpu_status_i; + rddata_reg(31 downto 19) <= (others => '0'); + ack_sreg(0) <= '1'; + ack_in_progress <= '1'; + end if; + end if; + end if; + end process; + +boot_done_o <= hot_boot; + +-- Drive the data output bus + slave_o.dat <= rddata_reg; + slave_o.stall <= (not ack_sreg(0)) and (slave_i.stb and slave_i.cyc); + slave_o.err <= '0'; + slave_o.rty <= '0'; +-- ACK signal generation. Just pass the LSB of ACK counter. + slave_o.ack <= ack_sreg(0); + slave_o.int <= '0'; +end rtl; \ No newline at end of file diff --git a/hdl/xwb_uart.vhd b/hdl/xwb_uart.vhd new file mode 100644 index 0000000000000000000000000000000000000000..d8c4f26dd4398dae246a1f8d02f3a14e7243e446 --- /dev/null +++ b/hdl/xwb_uart.vhd @@ -0,0 +1,86 @@ +library ieee; +use ieee.std_logic_1164.all; + +library work; +use work.wishbone_pkg.all; + +entity xwb_uart is + + port( + clk_sys_i : in std_logic; + rst_i : in std_logic; + + -- Wishbone + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; + +-- Port for BIT field: 'TX busy' in reg: 'Status Register' + uart_sr_tx_busy_i : in std_logic; +-- Port for MONOSTABLE field: 'TX trigger' in reg: 'Status Register' + uart_sr_tx_send_o : out std_logic; + uart_tdr_tx_data_o : out std_logic_vector(7 downto 0) + + ); + +end xwb_uart; + +architecture rtl of xwb_uart is + + +component wb_uart + port ( + rst_n_i : in std_logic; + clk_sys_i : in std_logic; + wb_adr_i : in std_logic_vector(0 downto 0); + wb_dat_i : in std_logic_vector(31 downto 0); + wb_dat_o : out std_logic_vector(31 downto 0); + wb_cyc_i : in std_logic; + wb_sel_i : in std_logic_vector(3 downto 0); + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_err_o : out std_logic; + wb_rty_o : out std_logic; + wb_stall_o : out std_logic; +-- Port for BIT field: 'TX busy' in reg: 'Status Register' + uart_sr_tx_busy_i : in std_logic; +-- Port for MONOSTABLE field: 'TX trigger' in reg: 'Status Register' + uart_sr_tx_send_o : out std_logic; +-- Port for std_logic_vector field: 'Transmit data' in reg: 'Transmit data register' + uart_tdr_tx_data_o : out std_logic_vector(7 downto 0) + ); +end component; +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + +begin + + + + U_Wrapped_UART: wb_uart + + port map ( + clk_sys_i => clk_sys_i, + rst_n_i => not rst_i, + wb_adr_i => slave_i.adr(2 downto 2), + wb_dat_i => slave_i.dat, + wb_dat_o => slave_o.dat, + wb_cyc_i => slave_i.cyc, + wb_sel_i => slave_i.sel, + wb_stb_i => slave_i.stb, + wb_we_i => slave_i.we, + wb_ack_o => slave_o.ack, + wb_stall_o => slave_o.stall, + uart_sr_tx_busy_i => uart_sr_tx_busy_i, + uart_sr_tx_send_o => uart_sr_tx_send_o, + uart_tdr_tx_data_o => uart_tdr_tx_data_o); + + slave_o.err <= '0'; + slave_o.rty <= '0'; + slave_o.int <='0'; + + desc_o <= (others => '0'); + + +end architecture; \ No newline at end of file diff --git a/hdl/xwb_wd_reg.vhd b/hdl/xwb_wd_reg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..bb73699a2de6424d28e7dd97e7fb9fc2d10fe2d5 --- /dev/null +++ b/hdl/xwb_wd_reg.vhd @@ -0,0 +1,83 @@ +library ieee; +use ieee.std_logic_1164.all; + +library work; +use work.wishbone_pkg.all; + +entity xwb_wd_reg is + + port( + clk_sys_i : in std_logic; + rst_i : in std_logic; + + -- Wishbone + slave_i : in t_wishbone_slave_in; + slave_o : out t_wishbone_slave_out; + desc_o : out t_wishbone_device_descriptor; +-- Port for MONOSTABLE field: 'Heartbeat' in reg: 'Watchdog' + wd_reg_heartbeat_o : out std_logic + ); + +end xwb_wd_reg; + +architecture rtl of xwb_wd_reg is + + + + +component wd_regs + port ( + rst_n_i : in std_logic; + clk_sys_i : in std_logic; + wb_dat_i : in std_logic_vector(31 downto 0); + wb_dat_o : out std_logic_vector(31 downto 0); + wb_cyc_i : in std_logic; + wb_sel_i : in std_logic_vector(3 downto 0); + wb_stb_i : in std_logic; + wb_we_i : in std_logic; + wb_ack_o : out std_logic; + wb_err_o : out std_logic; + wb_rty_o : out std_logic; + wb_stall_o : out std_logic; +-- Port for MONOSTABLE field: 'Heartbeat' in reg: 'Watchdog' + wd_reg_heartbeat_o : out std_logic + ); +end component; + +attribute syn_radhardlevel : string; +attribute syn_radhardlevel of rtl : architecture is "tmr"; + +begin + + + + + U_Wrapped_WD_regs: wd_regs + + port map ( + clk_sys_i => clk_sys_i, + rst_n_i => not rst_i, + -- wb_adr_i => slave_i.adr(4 downto 0), + wb_dat_i => slave_i.dat, + wb_dat_o => slave_o.dat, + wb_cyc_i => slave_i.cyc, + wb_sel_i => slave_i.sel, + wb_stb_i => slave_i.stb, + wb_we_i => slave_i.we, + wb_ack_o => slave_o.ack, + wb_stall_o => slave_o.stall, + wd_reg_heartbeat_o => wd_reg_heartbeat_o); + + slave_o.err <= '0'; + slave_o.rty <= '0'; + slave_o.int <='0'; + + desc_o <= (others => '0'); + + +end architecture; + + + + + diff --git a/hydra.prjx b/hydra.prjx new file mode 100644 index 0000000000000000000000000000000000000000..4aff430cf64325675657e2ba82f23b1dff72f44a --- /dev/null +++ b/hydra.prjx @@ -0,0 +1,1121 @@ +KEY LIBERO "11.8" +KEY CAPTURE "11.8.0.26" +KEY DEFAULT_IMPORT_LOC "C:\Actelprj\a2f-lnx-evb-2A\Emcraft_IP\PSRAM_SR" +KEY DEFAULT_OPEN_LOC "" +KEY ProjectID "0" +KEY HDLTechnology "VERILOG" +KEY VERILOGMODE "VERILOG2001" +KEY VHDLMODE "VHDL2008" +KEY UseConstraintFlowTechnology "TRUE" +KEY VendorTechnology_Family "SmartFusion2" +KEY VendorTechnology_Die "PA4M7500_N" +KEY VendorTechnology_Package "fg484" +KEY VendorTechnology_Speed "STD" +KEY VendorTechnology_DieVoltage "1.2" +KEY VendorTechnology_PART_RANGE "IND" +KEY VendorTechnology_DSW_VCCA_VOLTAGE_RAMP_RATE "1_MS" +KEY VendorTechnology_IO_DEFT_STD "LVCMOS33" +KEY VendorTechnology_OPCONR "" +KEY VendorTechnology_PLL_SUPPLY "PLL_SUPPLY_33" +KEY VendorTechnology_RAD_EXPOSURE "" +KEY VendorTechnology_RESERVEMIGRATIONPINS "1" +KEY VendorTechnology_RESTRICTPROBEPINS "0" +KEY VendorTechnology_RESTRICTSPIPINS "0" +KEY VendorTechnology_SYSTEM_CONTROLLER_SUSPEND_MODE "0" +KEY VendorTechnology_TARGETDEVICESFORMIGRATION "PA4M7500_N" +KEY VendorTechnology_TEMPR "COM" +KEY VendorTechnology_UNUSED_MSS_IO_RESISTOR_PULL "None" +KEY VendorTechnology_VCCI_1.2_VOLTR "COM" +KEY VendorTechnology_VCCI_1.5_VOLTR "COM" +KEY VendorTechnology_VCCI_1.8_VOLTR "COM" +KEY VendorTechnology_VCCI_2.5_VOLTR "COM" +KEY VendorTechnology_VCCI_3.3_VOLTR "COM" +KEY VendorTechnology_VOLTR "IND" +KEY ProjectLocation "C:\Users\mattia\Desktop\urv-core-rad\final-design\hydra" +KEY ProjectDescription "" +KEY Pa4PeripheralNewSeq "GOOD" +KEY SimulationType "VERILOG" +KEY Vendor "Actel" +KEY ActiveRoot "hydra::work" +LIST REVISIONS +VALUE="Impl1",NUM=1 +VALUE="Impl2",NUM=2 +CURREV=2 +ENDLIST +LIST FileManager +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS\1.1.500\MSS.cxf,actgen_cxf" +STATE="utd" +TIME="1607422610" +SIZE="526" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_CCC\1.0.100\MSS_CCC.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="253" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_CC\1.0.100\MSS_CC.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="252" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_CFGM\1.1.100\MSS_CFGM.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="254" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_CM3\1.0.200\MSS_CM3.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="253" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_DDRB\1.0.200\MSS_DDRB.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="254" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_EDAC\1.0.101\MSS_EDAC.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="254" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_ENVM\1.0.101\MSS_ENVM.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="254" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_FIC32\1.0.100\MSS_FIC32.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="255" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_INTR\1.0.200\MSS_INTR.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="254" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_RESET\1.0.100\MSS_RESET.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="255" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_RTC\1.0.201\MSS_RTC.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="253" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_SECURITY\1.0.100\MSS_SECURITY.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="258" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\Actel\SmartFusion2MSS\MSS_SWITCH\1.0.101\MSS_SWITCH.cxf,actgen_cxf" +STATE="utd" +TIME="1607422603" +SIZE="256" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\component\work\hydra\hydra.cxf,actgen_cxf" +STATE="utd" +TIME="1607435680" +SIZE="4639" +ENDFILE +VALUE "<project>\component\work\hydra\hydra.v,hdl" +STATE="utd" +TIME="1607435679" +SIZE="8204" +PARENT="<project>\component\work\hydra\hydra.cxf" +IS_READONLY="TRUE" +ENDFILE +VALUE "<project>\component\work\hydra_MSS\hydra_MSS.cxf,actgen_cxf" +STATE="utd" +TIME="1607422611" +SIZE="11844" +ENDFILE +VALUE "<project>\component\work\hydra_MSS\hydra_MSS.v,hdl" +STATE="utd" +TIME="1607422610" +SIZE="48497" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +IS_READONLY="TRUE" +ENDFILE +VALUE "<project>\component\work\hydra_MSS\hydra_MSS_pre.v,hdl" +STATE="utd" +TIME="1607422609" +SIZE="64284" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +BEGIN_USE_CONSTRAINT +TOOL_CONSTRAINT_TYPE="ideSYNTHESIS" +TOOL_CONSTRAINT_USE="PRECISION_EXT" +END_USE_CONSTRAINT +USE_FOR_ANY_TOOL="FALSE" +IS_READONLY="TRUE" +ENDFILE +VALUE "<project>\component\work\hydra_MSS\hydra_MSS_pre.vhd,hdl" +STATE="utd" +TIME="1606772857" +SIZE="80667" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +BEGIN_USE_CONSTRAINT +TOOL_CONSTRAINT_TYPE="ideSYNTHESIS" +TOOL_CONSTRAINT_USE="PRECISION_EXT" +END_USE_CONSTRAINT +USE_FOR_ANY_TOOL="FALSE" +IS_READONLY="TRUE" +ENDFILE +VALUE "<project>\component\work\hydra_MSS\hydra_MSS_syn.v,hdl" +STATE="utd" +TIME="1607422609" +SIZE="56527" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +BEGIN_USE_CONSTRAINT +TOOL_CONSTRAINT_TYPE="ideSYNTHESIS" +TOOL_CONSTRAINT_USE="SYNPLIFY7_EXT" +END_USE_CONSTRAINT +USE_FOR_ANY_TOOL="FALSE" +IS_READONLY="TRUE" +ENDFILE +VALUE "<project>\constraint\fp\user.pdc,fp_pdc" +STATE="utd" +TIME="1606837432" +SIZE="891" +IS_TARGET="TRUE" +ENDFILE +VALUE "<project>\constraint\io\m2s050_som.io.pdc,io_pdc" +STATE="utd" +TIME="1606818694" +SIZE="3087" +ENDFILE +VALUE "<project>\constraint\timing.sdc,sdc" +STATE="utd" +TIME="1606769924" +SIZE="2151" +ENDFILE +VALUE "<project>\designer\impl2\hydra.ide_des,ide_des" +STATE="utd" +TIME="1607015706" +SIZE="404" +ENDFILE +VALUE "<project>\hdl\axis_assert.vhd,hdl" +STATE="utd" +TIME="1583233333" +SIZE="5469" +ENDFILE +VALUE "<project>\hdl\axis_fifo_cdc.vhd,hdl" +STATE="utd" +TIME="1569832340" +SIZE="12441" +ENDFILE +VALUE "<project>\hdl\clock_buffer.vhd,hdl" +STATE="utd" +TIME="1607430744" +SIZE="1021" +ENDFILE +VALUE "<project>\hdl\dpram_generic.vhd,hdl" +STATE="utd" +TIME="1607442917" +SIZE="12876" +ENDFILE +VALUE "<project>\hdl\ram_voter.vhd,hdl" +STATE="utd" +TIME="1563289215" +SIZE="2129" +ENDFILE +VALUE "<project>\hdl\reset_gen.vhd,hdl" +STATE="utd" +TIME="1607425407" +SIZE="1664" +ENDFILE +VALUE "<project>\hdl\rst_filter.vhd,hdl" +STATE="utd" +TIME="1570774742" +SIZE="866" +ENDFILE +VALUE "<project>\hdl\sdram_cdc_r.vhd,hdl" +STATE="utd" +TIME="1563881401" +SIZE="1664" +ENDFILE +VALUE "<project>\hdl\secded_ecc.vhd,hdl" +STATE="utd" +TIME="1607432749" +SIZE="12912" +ENDFILE +VALUE "<project>\hdl\secded_ecc_daec.vhd,hdl" +STATE="utd" +TIME="1570772004" +SIZE="17193" +ENDFILE +VALUE "<project>\hdl\seu_counters.vhd,hdl" +STATE="utd" +TIME="1561992949" +SIZE="2092" +ENDFILE +VALUE "<project>\hdl\uart.v,hdl" +STATE="utd" +TIME="1593365548" +SIZE="2316" +ENDFILE +VALUE "<project>\hdl\ueth.vhd,hdl" +STATE="utd" +TIME="1588249797" +SIZE="4891" +ENDFILE +VALUE "<project>\hdl\ueth_crc.vhd,hdl" +STATE="utd" +TIME="1593367576" +SIZE="3177" +ENDFILE +VALUE "<project>\hdl\ueth_dma.vhd,hdl" +STATE="utd" +TIME="1605105818" +SIZE="19463" +ENDFILE +VALUE "<project>\hdl\ueth_hub.vhd,hdl" +STATE="utd" +TIME="1593367593" +SIZE="7485" +ENDFILE +VALUE "<project>\hdl\ueth_mac.vhd,hdl" +STATE="utd" +TIME="1593367918" +SIZE="15827" +ENDFILE +VALUE "<project>\hdl\ueth_miim.vhd,hdl" +STATE="utd" +TIME="1607451522" +SIZE="5655" +ENDFILE +VALUE "<project>\hdl\ueth_uphy.vhd,hdl" +STATE="utd" +TIME="1593367542" +SIZE="4713" +ENDFILE +VALUE "<project>\hdl\urv_core_DTMR.vhd,hdl" +STATE="utd" +TIME="1593348949" +SIZE="13440" +ENDFILE +VALUE "<project>\hdl\urv_soc.vhd,hdl" +STATE="utd" +TIME="1607435517" +SIZE="30808" +ENDFILE +VALUE "<project>\hdl\urv_supervisor.vhd,hdl" +STATE="utd" +TIME="1604492687" +SIZE="4646" +ENDFILE +VALUE "<project>\hdl\wb_envm.vhd,hdl" +STATE="utd" +TIME="1604860502" +SIZE="7675" +ENDFILE +VALUE "<project>\hdl\wb_master_voter.vhd,hdl" +STATE="utd" +TIME="1592922124" +SIZE="1685" +ENDFILE +VALUE "<project>\hdl\wb_seu_reg.vhdl,hdl" +STATE="utd" +TIME="1561622710" +SIZE="4684" +ENDFILE +VALUE "<project>\hdl\wb_slave_voter.vhd,hdl" +STATE="utd" +TIME="1592922113" +SIZE="1154" +ENDFILE +VALUE "<project>\hdl\wb_uart.vhdl,hdl" +STATE="utd" +TIME="1592921902" +SIZE="7444" +ENDFILE +VALUE "<project>\hdl\wb_wd_reg.vhdl,hdl" +STATE="utd" +TIME="1564131777" +SIZE="5376" +ENDFILE +VALUE "<project>\hdl\xwb_ram_adapter.vhdl,hdl" +STATE="utd" +TIME="1605105986" +SIZE="8791" +ENDFILE +VALUE "<project>\hdl\xwb_seu_reg.vhd,hdl" +STATE="utd" +TIME="1593367659" +SIZE="3180" +ENDFILE +VALUE "<project>\hdl\xwb_supervisor_reg.vhd,hdl" +STATE="utd" +TIME="1604492831" +SIZE="2854" +ENDFILE +VALUE "<project>\hdl\xwb_uart.vhd,hdl" +STATE="utd" +TIME="1593367672" +SIZE="2888" +ENDFILE +VALUE "<project>\hdl\xwb_wd_reg.vhd,hdl" +STATE="utd" +TIME="1593367680" +SIZE="2215" +ENDFILE +VALUE "<project>\simulation\CM3_compile_bfm.tcl,sim" +STATE="utd" +TIME="1607422609" +SIZE="500" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\simulation\peripheral_init.bfm,sim" +STATE="utd" +TIME="1566480149" +SIZE="8450" +PARENT="<project>\component\Actel\SmartFusion2MSS\MSS\1.1.500\MSS.cxf" +ENDFILE +VALUE "<project>\simulation\subsystem.bfm,sim" +STATE="utd" +TIME="1607435679" +SIZE="602" +PARENT="<project>\component\work\hydra\hydra.cxf" +ENDFILE +VALUE "<project>\simulation\test.bfm,sim" +STATE="utd" +TIME="1607422609" +SIZE="734" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\simulation\user.bfm,sim" +STATE="utd" +TIME="1606762191" +SIZE="555" +PARENT="<project>\component\work\hydra_MSS\hydra_MSS.cxf" +ENDFILE +VALUE "<project>\synthesis\hydra_syn.prj,prj" +STATE="utd" +TIME="1607425586" +SIZE="8370" +ENDFILE +VALUE "<project>\synthesis\rev_1\hydra.edn,syn_edn" +STATE="ood" +TIME="1607009112" +SIZE="24838895" +ENDFILE +VALUE "<project>\synthesis\rev_1\hydra.so,so" +STATE="utd" +TIME="1607425585" +SIZE="246" +ENDFILE +VALUE "<project>\synthesis\rev_1\hydra.v,syn_hdl" +STATE="ood" +TIME="1607425599" +SIZE="7327805" +ENDFILE +VALUE "<project>\synthesis\rev_1\hydra_sdc.sdc,syn_sdc" +STATE="ood" +TIME="1607009111" +SIZE="2066" +ENDFILE +VALUE "<project>\synthesis\rev_1\hydra_vm.sdc,syn_sdc" +STATE="utd" +TIME="1607425582" +SIZE="2066" +ENDFILE +VALUE "<project>\synthesis\rev_2\hydra_pro.so,so" +STATE="utd" +TIME="1607441572" +SIZE="250" +ENDFILE +VALUE "<project>\synthesis\rev_2\hydra_pro.vm,syn_vm" +STATE="ood" +TIME="1607441874" +SIZE="8019400" +ENDFILE +VALUE "<project>\synthesis\rev_2\hydra_pro_vm.sdc,syn_sdc" +STATE="utd" +TIME="1607441572" +SIZE="3103" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_config.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1564556834" +SIZE="1435" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_cpu.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1568367999" +SIZE="11642" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_csr.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1592987380" +SIZE="4434" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_decode.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1564556834" +SIZE="9979" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_defs.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1568114320" +SIZE="3493" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_exceptions.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1568731323" +SIZE="4261" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_exec.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1604860468" +SIZE="14520" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_fetch.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1568104439" +SIZE="4881" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_regfile.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1568723867" +SIZE="4712" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_shifter.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1564556834" +SIZE="2999" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_timer.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1568104993" +SIZE="2311" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_writeback.v,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/urv-core-irq-patched/rtl" +STATE="utd" +TIME="1564556834" +SIZE="4472" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\wb_crossbar\sdb_rom.vhd,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/wb_crossbar" +STATE="utd" +TIME="1503998412" +SIZE="5750" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\wb_crossbar\wb_skidpad.vhd,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/wb_crossbar" +STATE="utd" +TIME="1503998412" +SIZE="2027" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\wb_crossbar\wishbone_pkg.vhd,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/wb_crossbar" +STATE="utd" +TIME="1564130312" +SIZE="87625" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_crossbar.vhd,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/wb_crossbar" +STATE="utd" +TIME="1561473300" +SIZE="16801" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_register_link.vhd,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/wb_crossbar" +STATE="utd" +TIME="1503998412" +SIZE="3016" +IS_READONLY="TRUE" +ENDFILE +VALUE "G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_sdb_crossbar.vhd,hdl" +LINKFILEROOT "G:/Users/r/rizzi/powerlink/wb_crossbar" +STATE="utd" +TIME="1503998412" +SIZE="9627" +IS_READONLY="TRUE" +ENDFILE +ENDLIST +LIST UsedFile +ENDLIST +LIST NewModulesInfo +LIST "hydra::work" +FILE "<project>\component\work\hydra\hydra.v,hdl" +LIST Other_Association +VALUE "<project>\simulation\subsystem.bfm,sim" +ENDLIST +LIST UserCustomizedFileList +LIST "ideCOMPILENETLIST" +USE_LIST=TRUE +FILELIST +VALUE "<project>\synthesis\rev_1\hydra.vm,syn_vm" +ENDFILELIST +ENDLIST +ENDLIST +LIST SynthesisConstraints +VALUE "<project>\constraint\timing.sdc,sdc" +ENDLIST +LIST TimingConstraints +VALUE "<project>\constraint\timing.sdc,sdc" +ENDLIST +LIST ProjectState5.1 +LIST Impl1 +LIST FlowOptions +UsePhySynth=FALSE +UseSynth=FALSE +UseFhbAutoInst=FALSE +ENDLIST +Used_File_List +VALUE "<project>\synthesis\hydra.edn,syn_edn" +VALUE "<project>\synthesis\hydra.v,syn_hdl" +VALUE "<project>\phy_synthesis\hydra_palace.edn,palace_edn" +VALUE "<project>\phy_synthesis\hydra_palace.gcf,palace_gcf" +VALUE "<project>\phy_synthesis\hydra_palace.pdc,palace_pdc" +VALUE "<project>\phy_synthesis\hydra_palace.sdc,palace_sdc" +VALUE "<project>\phy_synthesis\hydra_palace.v,palace_hdl" +VALUE "<project>\designer\impl1\hydra.adb,adb" +VALUE "<project>\designer\impl1\hydra.fdb,fdb" +VALUE "<project>\designer\impl1\hydra.pdb,pdb" +VALUE "<project>\designer\impl1\hydra.stp,stp" +VALUE "<project>\designer\impl1\hydra_fp\hydra.pro,pro" +VALUE "<project>\synthesis\hydra.vm,syn_vm" +VALUE "<project>\synthesis\hydra_sdc.sdc,syn_sdc" +ENDUsed_File_List +ENDLIST +LIST Impl2 +LIST FlowOptions +UsePhySynth=FALSE +UseSynth=TRUE +UseFhbAutoInst=FALSE +ENDLIST +Used_File_List +VALUE "<project>\synthesis\hydra.edn,syn_edn" +VALUE "<project>\synthesis\hydra.v,syn_hdl" +VALUE "<project>\phy_synthesis\hydra_palace.edn,palace_edn" +VALUE "<project>\phy_synthesis\hydra_palace.gcf,palace_gcf" +VALUE "<project>\phy_synthesis\hydra_palace.pdc,palace_pdc" +VALUE "<project>\phy_synthesis\hydra_palace.sdc,palace_sdc" +VALUE "<project>\phy_synthesis\hydra_palace.v,palace_hdl" +VALUE "<project>\synthesis\rev_2\hydra_pro.vm,syn_vm" +VALUE "<project>\synthesis\rev_2\hydra_pro_sdc.sdc,syn_sdc" +ENDUsed_File_List +ENDLIST +ENDLIST +ENDLIST +LIST "hydra_MSS::work" +FILE "<project>\component\work\hydra_MSS\hydra_MSS.v,hdl" +LIST Other_Association +VALUE "<project>\simulation\CM3_compile_bfm.tcl,sim" +VALUE "<project>\simulation\user.bfm,sim" +VALUE "<project>\simulation\test.bfm,sim" +VALUE "<project>\simulation\peripheral_init.bfm,sim" +ENDLIST +ENDLIST +ENDLIST +LIST AssociatedStimulus +ENDLIST +LIST Other_Association +LIST hydra +VALUE "<project>\simulation\subsystem.bfm,sim" +ENDLIST +LIST hydra_MSS +VALUE "<project>\simulation\CM3_compile_bfm.tcl,sim" +VALUE "<project>\simulation\user.bfm,sim" +VALUE "<project>\simulation\test.bfm,sim" +VALUE "<project>\simulation\peripheral_init.bfm,sim" +ENDLIST +ENDLIST +LIST SimulationOptions +UseAutomaticDoFile=true +IncludeWaveDo=false +Type=max +RunTime=1000ns +Resolution=1fs +VsimOpt= +EntityName=testbench +TopInstanceName=<top>_0 +DoFileName= +DoFileName2=wave.do +DoFileParams= +DisplayDUTWave=false +LogAllSignals=false +DisablePulseFiltering=false +DumpVCD=false +VCDFileName=power.vcd +VHDL2008=false +Verilog2001=false +SystemVerilog=false +TimeUnit=1 +TimeUnitBase=ns +Precision=100 +PrecisionBase=ps +ENDLIST +LIST ModelSimLibPath +UseCustomPath=FALSE +LibraryPath= +ENDLIST +LIST GlobalFlowOptions +GenerateHDLAfterSynthesis=FALSE +GenerateHDLAfterPhySynthesis=FALSE +RunDRCAfterSynthesis=FALSE +AutoCheckConstraints=TRUE +UpdateModelSimIni=TRUE +NoIOMode=FALSE +PeriInitStandalone=FALSE +EnableViewDraw=FALSE +UpdateViewDrawIni=TRUE +GenerateHDLFromSchematic=TRUE +VmNetlistFlowOn=TRUE +EnableDesignSeparationOn=FALSE +EnableSETMitigationOn=FALSE +DisplayFanoutLimit=10 +AbortFlowOnPDCErrorsOn=TRUE +AbortFlowOnSDCErrorsOn=TRUE +FlashProInputFile=pdb +SmartGenCompileReport=T +ENDLIST +LIST PhySynthesisOptions +ENDLIST +LIST Profiles +NAME="SoftConsole" +FUNCTION="SoftwareIDE" +TOOL="SoftConsole" +LOCATION="eclipse.exe" +PARAM="" +BATCH=0 +LICENSE="" +IS32BIT="1" +EndProfile +NAME="Synplify Pro ME" +FUNCTION="Synthesis" +TOOL="Synplify Pro ME" +LOCATION="C:\Microsemi\Libero_SoC_v11.8\SynplifyPro\bin\synplify_pro.exe" +PARAM="-licensetype synplifypro_actel -batch -log synplify.log" +BATCH=1 +LICENSE="" +IS32BIT="1" +EndProfile +NAME="ModelSim" +FUNCTION="Simulation" +TOOL="ModelSim" +LOCATION="modelsim.exe" +PARAM="" +BATCH=0 +LICENSE="" +IS32BIT="1" +EndProfile +NAME="FPExpress" +FUNCTION="Program" +TOOL="FlashPro" +LOCATION="C:\Microsemi\Libero_SoC_v11.8\Designer\bin\FPExpress.exe" +PARAM="" +BATCH=0 +LICENSE="" +IS32BIT="1" +EndProfile +NAME="Identify Debugger" +FUNCTION="IdentifyDebugger" +TOOL="Identify Debugger" +LOCATION="C:\Microsemi\Libero_SoC_v11.8\Identify\bin\identify_debugger.exe" +PARAM="" +BATCH=0 +LICENSE="" +IS32BIT="1" +EndProfile +ENDLIST +LIST ProjectState5.1 +LIST "hydra::work" +LIST Impl1 +LIST FlowOptions +UsePhySynth=FALSE +UseSynth=FALSE +UseFhbAutoInst=FALSE +ENDLIST +Used_File_List +VALUE "<project>\synthesis\hydra.edn,syn_edn" +VALUE "<project>\synthesis\hydra.v,syn_hdl" +VALUE "<project>\phy_synthesis\hydra_palace.edn,palace_edn" +VALUE "<project>\phy_synthesis\hydra_palace.gcf,palace_gcf" +VALUE "<project>\phy_synthesis\hydra_palace.pdc,palace_pdc" +VALUE "<project>\phy_synthesis\hydra_palace.sdc,palace_sdc" +VALUE "<project>\phy_synthesis\hydra_palace.v,palace_hdl" +VALUE "<project>\designer\impl1\hydra.adb,adb" +VALUE "<project>\designer\impl1\hydra.fdb,fdb" +VALUE "<project>\designer\impl1\hydra.pdb,pdb" +VALUE "<project>\designer\impl1\hydra.stp,stp" +VALUE "<project>\designer\impl1\hydra_fp\hydra.pro,pro" +VALUE "<project>\synthesis\hydra.vm,syn_vm" +VALUE "<project>\synthesis\hydra_sdc.sdc,syn_sdc" +ENDUsed_File_List +ENDLIST +LIST Impl2 +LIST FlowOptions +UsePhySynth=FALSE +UseSynth=TRUE +UseFhbAutoInst=FALSE +ENDLIST +Used_File_List +VALUE "<project>\synthesis\hydra.edn,syn_edn" +VALUE "<project>\synthesis\hydra.v,syn_hdl" +VALUE "<project>\phy_synthesis\hydra_palace.edn,palace_edn" +VALUE "<project>\phy_synthesis\hydra_palace.gcf,palace_gcf" +VALUE "<project>\phy_synthesis\hydra_palace.pdc,palace_pdc" +VALUE "<project>\phy_synthesis\hydra_palace.sdc,palace_sdc" +VALUE "<project>\phy_synthesis\hydra_palace.v,palace_hdl" +VALUE "<project>\synthesis\rev_2\hydra_pro.vm,syn_vm" +VALUE "<project>\synthesis\rev_2\hydra_pro_sdc.sdc,syn_sdc" +ENDUsed_File_List +ENDLIST +ENDLIST +ENDLIST +LIST ExcludePackageForSimulation +ENDLIST +LIST ExcludePackageForSynthesis +ENDLIST +LIST IncludeModuleForSimulation +ENDLIST +LIST CDBOrder +ENDLIST +LIST UserCustomizedFileList +LIST "hydra" +LIST "ideCOMPILENETLIST" +USE_LIST=TRUE +FILELIST +VALUE "<project>\synthesis\rev_1\hydra.vm,syn_vm" +ENDFILELIST +ENDLIST +ENDLIST +ENDLIST +LIST OpenedFileList +ORIENTATION;HORIZONTAL +Reports;Reports;0 +ReportsCurrentItem;Run PROGRAM Action:hydra_PROGRAM.log +HDL;hdl\dpram_generic.vhd;0 +HDL;hdl\urv_soc.vhd;0 +HDL;constraint\fp\user.pdc;0 +HDL;hdl\axis_fifo_cdc.vhd;0 +StartPage;StartPage;0 +HDL;constraint\io\m2s050_som.io.pdc;0 +HDL;synthesis\hydra.srr;0 +HDL;hdl\reset_gen.vhd;0 +SmartDesign;hydra;0 +HDL;hdl\ueth_dma.vhd;0 +Constraint Manager;Constraint Manager;0 +SmartDesign;hydra_MSS;0 +HDL;constraint\timing.sdc;0 +HDL;hdl\axis_assert.vhd;0 +ACTIVEVIEW;hdl\dpram_generic.vhd +ENDLIST +LIST ModuleSubBlockList +LIST "axis_assert::work","hdl\axis_assert.vhd","FALSE","FALSE" +ENDLIST +LIST "axis_fifo_cdc::work","hdl\axis_fifo_cdc.vhd","FALSE","FALSE" +SUBBLOCK "sdpram_cdc_r::work","hdl\sdram_cdc_r.vhd","FALSE","FALSE" +ENDLIST +LIST "clock_buffer::work","hdl\clock_buffer.vhd","FALSE","FALSE" +ENDLIST +LIST "dpram_generic::work","hdl\dpram_generic.vhd","FALSE","FALSE" +ENDLIST +LIST "hydra::work","component\work\hydra\hydra.v","TRUE","FALSE" +SUBBLOCK "clock_buffer::work","hdl\clock_buffer.vhd","FALSE","FALSE" +SUBBLOCK "hydra_MSS::work","component\work\hydra_MSS\hydra_MSS.v","TRUE","FALSE" +SUBBLOCK "reset_gen::work","hdl\reset_gen.vhd","FALSE","FALSE" +SUBBLOCK "urv_soc::work","hdl\urv_soc.vhd","FALSE","FALSE" +ENDLIST +LIST "hydra_MSS::work","component\work\hydra_MSS\hydra_MSS.v","TRUE","FALSE" +SUBBLOCK "MSS_075::work","component\work\hydra_MSS\hydra_MSS_syn.v","FALSE","FALSE" +ENDLIST +LIST "MSS_075::work","component\work\hydra_MSS\hydra_MSS_syn.v","FALSE","FALSE" +ENDLIST +LIST "ram_voter::work","hdl\ram_voter.vhd","FALSE","FALSE" +ENDLIST +LIST "reset_gen::work","hdl\reset_gen.vhd","FALSE","FALSE" +ENDLIST +LIST "rst_filter::work","hdl\rst_filter.vhd","FALSE","FALSE" +ENDLIST +LIST "sdb_rom::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\sdb_rom.vhd","FALSE","FALSE" +ENDLIST +LIST "sdpram_cdc_r::work","hdl\sdram_cdc_r.vhd","FALSE","FALSE" +ENDLIST +LIST "secded_ecc::work","hdl\secded_ecc.vhd","FALSE","FALSE" +ENDLIST +LIST "secded_ecc_daec::work","hdl\secded_ecc_daec.vhd","FALSE","FALSE" +ENDLIST +LIST "seu_counters::work","hdl\seu_counters.vhd","FALSE","FALSE" +ENDLIST +LIST "uart::work","hdl\uart.v","FALSE","FALSE" +ENDLIST +LIST "ueth::work","hdl\ueth.vhd","FALSE","FALSE" +SUBBLOCK "ueth_hub::work","hdl\ueth_hub.vhd","FALSE","FALSE" +SUBBLOCK "ueth_mac::work","hdl\ueth_mac.vhd","FALSE","FALSE" +SUBBLOCK "ueth_uphy::work","hdl\ueth_uphy.vhd","FALSE","FALSE" +ENDLIST +LIST "ueth_crc::work","hdl\ueth_crc.vhd","FALSE","FALSE" +ENDLIST +LIST "ueth_dma::work","hdl\ueth_dma.vhd","FALSE","FALSE" +ENDLIST +LIST "ueth_hub::work","hdl\ueth_hub.vhd","FALSE","FALSE" +ENDLIST +LIST "ueth_mac::work","hdl\ueth_mac.vhd","FALSE","FALSE" +SUBBLOCK "axis_fifo_cdc::work","hdl\axis_fifo_cdc.vhd","FALSE","FALSE" +SUBBLOCK "ueth_crc::work","hdl\ueth_crc.vhd","FALSE","FALSE" +SUBBLOCK "ueth_dma::work","hdl\ueth_dma.vhd","FALSE","FALSE" +SUBBLOCK "ueth_miim::work","hdl\ueth_miim.vhd","FALSE","FALSE" +ENDLIST +LIST "ueth_miim::work","hdl\ueth_miim.vhd","FALSE","FALSE" +ENDLIST +LIST "ueth_uphy::work","hdl\ueth_uphy.vhd","FALSE","FALSE" +SUBBLOCK "axis_fifo_cdc::work","hdl\axis_fifo_cdc.vhd","FALSE","FALSE" +ENDLIST +LIST "urv_core_DTMR::work","hdl\urv_core_DTMR.vhd","FALSE","FALSE" +SUBBLOCK "rst_filter::work","hdl\rst_filter.vhd","FALSE","FALSE" +SUBBLOCK "secded_ecc::work","hdl\secded_ecc.vhd","FALSE","FALSE" +SUBBLOCK "secded_ecc_daec::work","hdl\secded_ecc_daec.vhd","FALSE","FALSE" +SUBBLOCK "urv_cpu::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_cpu.v","FALSE","FALSE" +ENDLIST +LIST "urv_cpu::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_cpu.v","FALSE","FALSE" +SUBBLOCK "urv_decode::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_decode.v","FALSE","FALSE" +SUBBLOCK "urv_exec::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_exec.v","FALSE","FALSE" +SUBBLOCK "urv_fetch::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_fetch.v","FALSE","FALSE" +SUBBLOCK "urv_regfile::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_regfile.v","FALSE","FALSE" +SUBBLOCK "urv_timer::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_timer.v","FALSE","FALSE" +SUBBLOCK "urv_writeback::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_writeback.v","FALSE","FALSE" +ENDLIST +LIST "urv_csr::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_csr.v","FALSE","FALSE" +ENDLIST +LIST "urv_decode::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_decode.v","FALSE","FALSE" +ENDLIST +LIST "urv_exceptions::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_exceptions.v","FALSE","FALSE" +ENDLIST +LIST "urv_exec::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_exec.v","FALSE","FALSE" +SUBBLOCK "urv_csr::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_csr.v","FALSE","FALSE" +SUBBLOCK "urv_exceptions::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_exceptions.v","FALSE","FALSE" +SUBBLOCK "urv_shifter::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_shifter.v","FALSE","FALSE" +ENDLIST +LIST "urv_fetch::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_fetch.v","FALSE","FALSE" +ENDLIST +LIST "urv_regfile::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_regfile.v","FALSE","FALSE" +SUBBLOCK "urv_regmem::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_regfile.v","FALSE","FALSE" +ENDLIST +LIST "urv_regmem::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_regfile.v","FALSE","FALSE" +ENDLIST +LIST "urv_shifter::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_shifter.v","FALSE","FALSE" +ENDLIST +LIST "urv_soc::work","hdl\urv_soc.vhd","FALSE","FALSE" +SUBBLOCK "ram_voter::work","hdl\ram_voter.vhd","FALSE","FALSE" +SUBBLOCK "seu_counters::work","hdl\seu_counters.vhd","FALSE","FALSE" +SUBBLOCK "uart::work","hdl\uart.v","FALSE","FALSE" +SUBBLOCK "ueth::work","hdl\ueth.vhd","FALSE","FALSE" +SUBBLOCK "urv_core_DTMR::work","hdl\urv_core_DTMR.vhd","FALSE","FALSE" +SUBBLOCK "urv_supervisor::work","hdl\urv_supervisor.vhd","FALSE","FALSE" +SUBBLOCK "wb_envm::work","hdl\wb_envm.vhd","FALSE","FALSE" +SUBBLOCK "wb_master_voter::work","hdl\wb_master_voter.vhd","FALSE","FALSE" +SUBBLOCK "wb_slave_voter::work","hdl\wb_slave_voter.vhd","FALSE","FALSE" +SUBBLOCK "xwb_ram_adapter::work","hdl\xwb_ram_adapter.vhdl","FALSE","FALSE" +SUBBLOCK "xwb_seu_regs::work","hdl\xwb_seu_reg.vhd","FALSE","FALSE" +SUBBLOCK "xwb_uart::work","hdl\xwb_uart.vhd","FALSE","FALSE" +SUBBLOCK "xwb_wd_reg::work","hdl\xwb_wd_reg.vhd","FALSE","FALSE" +SUBBLOCK "dpram_generic::work","hdl\dpram_generic.vhd","FALSE","FALSE" +SUBBLOCK "xwb_crossbar::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_crossbar.vhd","FALSE","FALSE" +ENDLIST +LIST "urv_supervisor::work","hdl\urv_supervisor.vhd","FALSE","FALSE" +SUBBLOCK "xwb_supervisor_reg::work","hdl\xwb_supervisor_reg.vhd","FALSE","FALSE" +ENDLIST +LIST "urv_timer::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_timer.v","FALSE","FALSE" +ENDLIST +LIST "urv_writeback::work","G:\Users\r\rizzi\powerlink\urv-core-irq-patched\rtl\urv_writeback.v","FALSE","FALSE" +ENDLIST +LIST "voter::work","hdl\ram_voter.vhd","FALSE","FALSE" +ENDLIST +LIST "wb_async_bridge::work","","FALSE","FALSE" +ENDLIST +LIST "wb_envm::work","hdl\wb_envm.vhd","FALSE","FALSE" +ENDLIST +LIST "wb_gpio_port::work","","FALSE","FALSE" +ENDLIST +LIST "wb_i2c_bridge::work","","FALSE","FALSE" +ENDLIST +LIST "wb_i2c_master::work","","FALSE","FALSE" +ENDLIST +LIST "wb_master_voter::work","hdl\wb_master_voter.vhd","FALSE","FALSE" +ENDLIST +LIST "wb_master_voter_pkg::work","hdl\wb_master_voter.vhd","FALSE","FALSE" +ENDLIST +LIST "wb_onewire_master::work","","FALSE","FALSE" +ENDLIST +LIST "wb_serial_lcd::work","","FALSE","FALSE" +ENDLIST +LIST "wb_seu_regs::work","hdl\wb_seu_reg.vhdl","FALSE","FALSE" +ENDLIST +LIST "wb_simple_pwm::work","","FALSE","FALSE" +ENDLIST +LIST "wb_simple_uart::work","","FALSE","FALSE" +ENDLIST +LIST "wb_skidpad::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\wb_skidpad.vhd","FALSE","FALSE" +ENDLIST +LIST "wb_slave_adapter::work","","FALSE","FALSE" +ENDLIST +LIST "wb_slave_voter::work","hdl\wb_slave_voter.vhd","FALSE","FALSE" +ENDLIST +LIST "wb_slave_voter_pkg::work","hdl\wb_slave_voter.vhd","FALSE","FALSE" +ENDLIST +LIST "wb_spi::work","","FALSE","FALSE" +ENDLIST +LIST "wb_spi_flash::work","","FALSE","FALSE" +ENDLIST +LIST "wb_tics::work","","FALSE","FALSE" +ENDLIST +LIST "wb_uart::work","hdl\wb_uart.vhdl","FALSE","FALSE" +ENDLIST +LIST "wb_vic::work","","FALSE","FALSE" +ENDLIST +LIST "wd_regs::work","hdl\wb_wd_reg.vhdl","FALSE","FALSE" +ENDLIST +LIST "wishbone_pkg::work","G:\Users\r\rizzi\powerlink\wb_crossbar\wishbone_pkg.vhd","FALSE","FALSE" +SUBBLOCK "sdb_rom::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\sdb_rom.vhd","FALSE","FALSE" +SUBBLOCK "wb_async_bridge::work","","FALSE","FALSE" +SUBBLOCK "wb_gpio_port::work","","FALSE","FALSE" +SUBBLOCK "wb_i2c_bridge::work","","FALSE","FALSE" +SUBBLOCK "wb_i2c_master::work","","FALSE","FALSE" +SUBBLOCK "wb_onewire_master::work","","FALSE","FALSE" +SUBBLOCK "wb_serial_lcd::work","","FALSE","FALSE" +SUBBLOCK "wb_simple_pwm::work","","FALSE","FALSE" +SUBBLOCK "wb_simple_uart::work","","FALSE","FALSE" +SUBBLOCK "wb_skidpad::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\wb_skidpad.vhd","FALSE","FALSE" +SUBBLOCK "wb_slave_adapter::work","","FALSE","FALSE" +SUBBLOCK "wb_spi::work","","FALSE","FALSE" +SUBBLOCK "wb_spi_flash::work","","FALSE","FALSE" +SUBBLOCK "wb_tics::work","","FALSE","FALSE" +SUBBLOCK "wb_vic::work","","FALSE","FALSE" +SUBBLOCK "xwb_async_bridge::work","","FALSE","FALSE" +SUBBLOCK "xwb_bus_fanout::work","","FALSE","FALSE" +SUBBLOCK "xwb_clock_crossing::work","","FALSE","FALSE" +SUBBLOCK "xwb_crossbar::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_crossbar.vhd","FALSE","FALSE" +SUBBLOCK "xwb_dma::work","","FALSE","FALSE" +SUBBLOCK "xwb_dpram::work","","FALSE","FALSE" +SUBBLOCK "xwb_dpram_mixed::work","","FALSE","FALSE" +SUBBLOCK "xwb_gpio_port::work","","FALSE","FALSE" +SUBBLOCK "xwb_i2c_master::work","","FALSE","FALSE" +SUBBLOCK "xwb_lm32::work","","FALSE","FALSE" +SUBBLOCK "xwb_onewire_master::work","","FALSE","FALSE" +SUBBLOCK "xwb_register_link::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_register_link.vhd","FALSE","FALSE" +SUBBLOCK "xwb_sdb_crossbar::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_sdb_crossbar.vhd","FALSE","FALSE" +SUBBLOCK "xwb_simple_pwm::work","","FALSE","FALSE" +SUBBLOCK "xwb_simple_uart::work","","FALSE","FALSE" +SUBBLOCK "xwb_spi::work","","FALSE","FALSE" +SUBBLOCK "xwb_streamer::work","","FALSE","FALSE" +SUBBLOCK "xwb_tics::work","","FALSE","FALSE" +SUBBLOCK "xwb_vic::work","","FALSE","FALSE" +SUBBLOCK "xwb_xil_multiboot::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_async_bridge::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_bus_fanout::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_clock_crossing::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_crossbar::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_crossbar.vhd","FALSE","FALSE" +ENDLIST +LIST "xwb_dma::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_dpram::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_dpram_mixed::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_gpio_port::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_i2c_master::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_lm32::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_onewire_master::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_ram_adapter::work","hdl\xwb_ram_adapter.vhdl","FALSE","FALSE" +SUBBLOCK "secded_ecc::work","hdl\secded_ecc.vhd","FALSE","FALSE" +SUBBLOCK "secded_ecc_daec::work","hdl\secded_ecc_daec.vhd","FALSE","FALSE" +ENDLIST +LIST "xwb_register_link::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_register_link.vhd","FALSE","FALSE" +SUBBLOCK "wb_skidpad::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\wb_skidpad.vhd","FALSE","FALSE" +ENDLIST +LIST "xwb_sdb_crossbar::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_sdb_crossbar.vhd","FALSE","FALSE" +SUBBLOCK "sdb_rom::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\sdb_rom.vhd","FALSE","FALSE" +SUBBLOCK "xwb_crossbar::work::wishbone_pkg","G:\Users\r\rizzi\powerlink\wb_crossbar\xwb_crossbar.vhd","FALSE","FALSE" +ENDLIST +LIST "xwb_seu_regs::work","hdl\xwb_seu_reg.vhd","FALSE","FALSE" +SUBBLOCK "wb_seu_regs::work","hdl\wb_seu_reg.vhdl","FALSE","FALSE" +ENDLIST +LIST "xwb_simple_pwm::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_simple_uart::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_spi::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_streamer::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_supervisor_reg::work","hdl\xwb_supervisor_reg.vhd","FALSE","FALSE" +ENDLIST +LIST "xwb_tics::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_uart::work","hdl\xwb_uart.vhd","FALSE","FALSE" +SUBBLOCK "wb_uart::work","hdl\wb_uart.vhdl","FALSE","FALSE" +ENDLIST +LIST "xwb_vic::work","","FALSE","FALSE" +ENDLIST +LIST "xwb_wd_reg::work","hdl\xwb_wd_reg.vhd","FALSE","FALSE" +SUBBLOCK "wd_regs::work","hdl\wb_wd_reg.vhdl","FALSE","FALSE" +ENDLIST +LIST "xwb_xil_multiboot::work","","FALSE","FALSE" +ENDLIST +ENDLIST +LIST ActiveTestBenchList +ENDLIST +LIST IOTabList +VALUE "constraint\io\m2s050_som.io.pdc" +ENDLIST +LIST FPTabList +VALUE "constraint\fp\user.pdc" +ENDLIST +LIST TimingTabList +VALUE "constraint\timing.sdc" +ENDLIST +LIST FDCTabList +ENDLIST