URL
https://opencores.org/ocsvn/spacewire_light/spacewire_light/trunk
Subversion Repositories spacewire_light
Compare Revisions
- This comparison shows the changes necessary to convert path
/spacewire_light/trunk
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/bench/vhdl/streamtest_tb.vhd
0,0 → 1,242
-- |
-- Test bench for spwstream. |
-- |
-- Tests: |
-- * one spwstream instance with SpaceWire signals looped back to itself |
-- * sending of bytes, packets and time codes through the SpaceWire link |
-- * handling of link disabling and link disconnection |
-- |
-- This test bench is intended to test the buffering logic in spwstream. |
-- It does not thoroughly verify behaviour of the receiver, transmitter, |
-- signal patterns etc. Please use spwlink_tb.vhd to test those aspects. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use std.textio.all; |
use work.spwpkg.all; |
|
entity streamtest_tb is |
end entity; |
|
architecture tb_arch of streamtest_tb is |
|
-- Parameters. |
constant sys_clock_freq: real := 20.0e6; |
|
component streamtest is |
generic ( |
sysfreq: real; |
tickdiv: integer range 12 to 24 := 20; |
rximpl: spw_implementation_type := impl_generic; |
rxchunk: integer range 1 to 4 := 1; |
tximpl: spw_implementation_type := impl_generic; |
rxfifosize_bits: integer range 6 to 14 := 11; |
txfifosize_bits: integer range 2 to 14 := 11 ); |
port ( |
clk: in std_logic; |
rxclk: in std_logic; |
txclk: in std_logic; |
rst: in std_logic; |
linkstart: in std_logic; |
autostart: in std_logic; |
linkdisable: in std_logic; |
senddata: in std_logic; |
sendtick: in std_logic; |
txdivcnt: in std_logic_vector(7 downto 0); |
linkstarted: out std_logic; |
linkconnecting: out std_logic; |
linkrun: out std_logic; |
linkerror: out std_logic; |
gotdata: out std_logic; |
dataerror: out std_logic; |
tickerror: out std_logic; |
spw_di: in std_logic; |
spw_si: in std_logic; |
spw_do: out std_logic; |
spw_so: out std_logic ); |
end component; |
|
signal sys_clock_enable: std_logic := '0'; |
signal sysclk: std_logic := '0'; |
signal s_loopback: std_logic := '0'; |
signal s_nreceived: integer := 0; |
|
signal s_rst: std_logic := '1'; |
signal s_linkstart: std_logic; |
signal s_autostart: std_logic; |
signal s_linkdisable: std_logic; |
signal s_divcnt: std_logic_vector(7 downto 0); |
signal s_linkrun: std_logic; |
signal s_linkerror: std_logic; |
signal s_gotdata: std_logic; |
signal s_dataerror: std_logic; |
signal s_tickerror: std_logic; |
signal s_spwdi: std_logic; |
signal s_spwsi: std_logic; |
signal s_spwdo: std_logic; |
signal s_spwso: std_logic; |
|
begin |
|
-- streamtest instance |
streamtest_inst: streamtest |
generic map ( |
sysfreq => sys_clock_freq, |
tickdiv => 16, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_generic, |
rxfifosize_bits => 9, |
txfifosize_bits => 8 ) |
port map ( |
clk => sysclk, |
rxclk => sysclk, |
txclk => sysclk, |
rst => s_rst, |
linkstart => s_linkstart, |
autostart => s_autostart, |
linkdisable => s_linkdisable, |
senddata => '1', |
sendtick => '1', |
txdivcnt => s_divcnt, |
linkstarted => open, |
linkconnecting => open, |
linkrun => s_linkrun, |
linkerror => s_linkerror, |
gotdata => s_gotdata, |
dataerror => s_dataerror, |
tickerror => s_tickerror, |
spw_di => s_spwdi, |
spw_si => s_spwsi, |
spw_do => s_spwdo, |
spw_so => s_spwso ); |
|
-- Conditional loopback of SpaceWire signals. |
s_spwdi <= s_spwdo when (s_loopback = '1') else '0'; |
s_spwsi <= s_spwso when (s_loopback = '1') else '0'; |
|
-- Generate system clock. |
process is |
begin |
if sys_clock_enable /= '1' then |
wait until sys_clock_enable = '1'; |
end if; |
sysclk <= '1'; |
wait for (0.5 sec) / sys_clock_freq; |
sysclk <= '0'; |
wait for (0.5 sec) / sys_clock_freq; |
end process; |
|
-- Verify that error indications remain off. |
process is |
begin |
wait on s_linkerror, s_dataerror, s_tickerror; |
assert s_dataerror = '0' report "Detected data error"; |
assert s_tickerror = '0' report "Detected time code error"; |
if s_loopback = '1' then |
assert s_linkerror /= '1' report "Unexpected link error"; |
end if; |
end process; |
|
-- Verify that data is received regularly when the link is up. |
process is |
begin |
if s_linkrun = '0' or s_gotdata = '1' then |
wait until s_linkrun = '1' and s_gotdata = '0'; |
end if; |
wait until s_gotdata = '1' or s_linkrun = '0' for 3 ms; |
if s_linkrun = '1' then |
assert s_gotdata = '1' report "Link running but no data received"; |
end if; |
end process; |
|
-- Count number of received characters. |
process is |
begin |
wait until rising_edge(sysclk); |
if s_gotdata = '1' then |
s_nreceived <= s_nreceived + 1; |
end if; |
end process; |
|
-- Main process. |
process is |
variable vline: LINE; |
begin |
report "Starting streamtest test bench"; |
|
-- Initialize. |
s_loopback <= '1'; |
s_rst <= '1'; |
s_linkstart <= '0'; |
s_autostart <= '0'; |
s_linkdisable <= '0'; |
s_divcnt <= "00000001"; |
sys_clock_enable <= '1'; |
wait for 1 us; |
|
-- Test link and data transmission. |
report "Testing txdivcnt = 1"; |
s_rst <= '0'; |
s_linkstart <= '1'; |
wait for 100 us; |
assert s_linkrun = '1' report "Link failed to start"; |
wait for 50 ms; |
|
-- Check number of received characters. |
write(vline, string'("Received ")); |
write(vline, s_nreceived); |
write(vline, string'(" characters in 50 ms.")); |
writeline(output, vline); |
assert s_nreceived > 24000 report "Too few characters received"; |
|
-- Test switching to different transmission rate. |
report "Testing txdivcnt = 2"; |
s_divcnt <= "00000010"; |
wait for 10 ms; |
report "Testing txdivcnt = 3"; |
s_divcnt <= "00000011"; |
wait for 10 ms; |
|
-- Disable and re-enable link. |
report "Testing link disable/re-enable"; |
s_linkdisable <= '1'; |
s_divcnt <= "00000001"; |
wait for 2 ms; |
s_linkdisable <= '0'; |
wait for 100 us; |
assert s_linkrun = '1' report "Link failed to start after re-enable"; |
wait for 10 ms; |
|
-- Cut and reconnect loopback wiring. |
report "Testing physical disconnect/reconnect"; |
s_loopback <= '0'; |
wait for 2 ms; |
s_loopback <= '1'; |
wait for 100 us; |
assert s_linkrun = '1' report "Link failed to start after reconnect"; |
wait for 10 ms; |
s_loopback <= '0'; |
wait for 2 ms; |
s_loopback <= '1'; |
wait for 100 us; |
assert s_linkrun = '1' report "Link failed to start after reconnect (2)"; |
wait for 10 ms; |
|
-- Shut down. |
s_rst <= '1'; |
wait for 1 us; |
sys_clock_enable <= '0'; |
|
write(vline, string'("Received ")); |
write(vline, s_nreceived); |
write(vline, string'(" characters.")); |
writeline(output, vline); |
|
report "Done"; |
wait; |
end process; |
|
end architecture tb_arch; |
/bench/vhdl/spwlink_tb_all.vhd
0,0 → 1,326
-- |
-- Run the spwlink test bench in a several configurations. |
-- |
|
use work.spwpkg.all; |
|
entity spwlink_tb_all is |
end entity; |
|
architecture tb_arch of spwlink_tb_all is |
|
component spwlink_tb is |
generic ( |
sys_clock_freq: real := 20.0e6 ; |
rx_clock_freq: real := 20.0e6 ; |
tx_clock_freq: real := 20.0e6 ; |
input_rate: real := 10.0e6 ; |
tx_clock_div: integer := 1 ; |
rximpl: spw_implementation_type := impl_generic ; |
rxchunk: integer := 1 ; |
tximpl: spw_implementation_type := impl_generic ; |
startwait: time := 0 sec ); |
end component; |
|
begin |
|
-- Test 1: default configuration |
test1: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 1, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_generic, |
startwait => 0 ms ); |
|
-- Test 2: 18 Mbit input |
test2: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 18.0e6, |
tx_clock_div => 1, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_generic, |
startwait => 1 ms ); |
|
-- Test 3: 2 Mbit input |
test3: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 2.0e6, |
tx_clock_div => 1, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_generic, |
startwait => 2 ms ); |
|
-- Test 4: 20 Mbit output |
test4: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 0, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_generic, |
startwait => 3 ms ); |
|
-- Test 5: fast receiver, 10 Mbit in |
test5: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 1, |
rximpl => impl_fast, |
rxchunk => 1, |
tximpl => impl_generic, |
startwait => 4 ms ); |
|
-- Test 6: fast receiver, 18 Mbit in |
test6: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 18.0e6, |
tx_clock_div => 1, |
rximpl => impl_fast, |
rxchunk => 1, |
tximpl => impl_generic, |
startwait => 5 ms ); |
|
-- Test 7: fast receiver, 35 Mbit in |
test7: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 35.0e6, |
tx_clock_div => 1, |
rximpl => impl_fast, |
rxchunk => 2, |
tximpl => impl_generic, |
startwait => 6 ms ); |
|
-- Test 8: fast receiver, 55 Mbit in |
test8: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 30.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 55.0e6, |
tx_clock_div => 1, |
rximpl => impl_fast, |
rxchunk => 3, |
tximpl => impl_generic, |
startwait => 7 ms ); |
|
-- Test 9: fast receiver, 75 Mbit in |
test9: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 40.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 75.0e6, |
tx_clock_div => 1, |
rximpl => impl_fast, |
rxchunk => 4, |
tximpl => impl_generic, |
startwait => 8 ms ); |
|
-- Test 10: fast receiver, 75 Mbit in, 100 MHz sample clock |
test10: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 100.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 75.0e6, |
tx_clock_div => 1, |
rximpl => impl_fast, |
rxchunk => 4, |
tximpl => impl_generic, |
startwait => 9 ms ); |
|
-- Test 11: fast receiver, 2 Mbit in, 100 MHz sample clock |
test11: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 100.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 2.0e6, |
tx_clock_div => 1, |
rximpl => impl_fast, |
rxchunk => 4, |
tximpl => impl_generic, |
startwait => 10 ms ); |
|
-- Test 12: fast receiver, 67.13 Mbit in, 43 MHz sample clock |
test12: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 43.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 67.13e6, |
tx_clock_div => 1, |
rximpl => impl_fast, |
rxchunk => 4, |
tximpl => impl_generic, |
startwait => 11 ms ); |
|
-- Test 13: fast transmitter, 39/2 Mbit out |
test13: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 39.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 1, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_fast, |
startwait => 12 ms ); |
|
-- Test 14: fast transmitter, 39 Mbit out |
test14: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 39.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 0, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_fast, |
startwait => 13 ms ); |
|
-- Test 15: fast transmitter, 80 Mbit out |
test15: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 80.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 0, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_fast, |
startwait => 14 ms ); |
|
-- Test 16: fast transmitter, 20/3 Mbit out |
test16: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 20.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 2, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_fast, |
startwait => 15 ms ); |
|
-- Test 17: fast transmitter, 80/4 Mbit out |
test17: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 80.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 3, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_fast, |
startwait => 16 ms ); |
|
-- Test 18: fast transmitter, 80/5 Mbit out |
test18: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 80.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 4, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_fast, |
startwait => 17 ms ); |
|
-- Test 19: fast transmitter, 80/40 Mbit out |
test19: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 80.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 39, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_fast, |
startwait => 18 ms ); |
|
-- Test 20: fast transmitter, 200/97 Mbit out |
test20: spwlink_tb |
generic map ( |
sys_clock_freq => 50.0e6, |
rx_clock_freq => 50.0e6, |
tx_clock_freq => 200.0e6, |
input_rate => 10.0e6, |
tx_clock_div => 96, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_fast, |
startwait => 19 ms ); |
|
-- Test 21: fast transmitter, 78.5/2 Mbit out |
test21: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 20.0e6, |
tx_clock_freq => 78.5e6, |
input_rate => 10.0e6, |
tx_clock_div => 1, |
rximpl => impl_generic, |
rxchunk => 1, |
tximpl => impl_fast, |
startwait => 20 ms ); |
|
-- Test 22: fast receiver and fast transmitter, 78.5 Mbit out |
test22: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 43.0e6, |
tx_clock_freq => 78.5e6, |
input_rate => 67.13e6, |
tx_clock_div => 0, |
rximpl => impl_fast, |
rxchunk => 4, |
tximpl => impl_fast, |
startwait => 21 ms ); |
|
-- Test 23: fast receiver and fast transmitter, 77.5/2 Mbit out |
test23: spwlink_tb |
generic map ( |
sys_clock_freq => 20.0e6, |
rx_clock_freq => 43.0e6, |
tx_clock_freq => 77.5e6, |
input_rate => 67.13e6, |
tx_clock_div => 1, |
rximpl => impl_fast, |
rxchunk => 4, |
tximpl => impl_fast, |
startwait => 22 ms ); |
|
end tb_arch; |
/bench/vhdl/spwlink_tb.vhd
0,0 → 1,978
-- |
-- Test Bench for Link interface. |
-- |
-- Unfortunately rather incomplete. |
-- The following items are verified: |
-- * reset; |
-- * link start, NULL exchange, FCT exchange; |
-- * link autostart on first NULL; |
-- * send/receive time codes, data characters, EOP/EEP; |
-- * detection of timeout, disconnection, parity error, escape error. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all, ieee.numeric_std.all; |
use std.textio.all; |
use work.spwpkg.all; |
|
entity spwlink_tb is |
|
-- Tests should be done with several different combinations |
-- of values for the generics. |
generic ( |
|
-- System clock frequency |
sys_clock_freq: real := 20.0e6 ; |
|
-- Receiver sample clock frequency |
rx_clock_freq: real := 20.0e6 ; |
|
-- Transmitter clock frequency |
tx_clock_freq: real := 20.0e6 ; |
|
-- Input bit rate |
input_rate: real := 10.0e6 ; |
|
-- TX clock division factor (actual factor is one tx_clock_div+1) |
tx_clock_div: integer := 1 ; |
|
-- Receiver implementation |
rximpl: spw_implementation_type := impl_generic ; |
|
-- Bits per sysclk for fast receiver |
rxchunk: integer := 1 ; |
|
-- Transmitter implementation |
tximpl: spw_implementation_type := impl_generic ; |
|
-- Wait before starting test bench |
startwait: time := 0 sec |
); |
|
end spwlink_tb; |
|
architecture tb_arch of spwlink_tb is |
|
-- Bit periods for incoming / outgoing signal |
constant inbit_period: time := (1 sec) / input_rate ; |
constant outbit_period: time := (1 sec) * real(tx_clock_div + 1) / tx_clock_freq ; |
constant txclk_period: time := (1 sec) / tx_clock_freq ; |
|
-- clock generation |
signal sys_clock_enable: std_logic := '0'; |
signal sysclk: std_logic; |
signal rxclk: std_logic; |
signal txclk: std_logic; |
|
-- output monitoring |
type t_output_chars is array(natural range <>) of std_logic_vector(9 downto 0); |
signal output_collect: std_logic; |
signal output_ptr: integer; |
signal output_bits: std_logic_vector(0 to 4095); |
signal output_nchars: integer; |
signal output_chars: t_output_chars(0 to 4095); |
|
-- input generation |
signal input_par: std_logic; |
signal input_idle: std_logic; |
signal input_pattern: integer := 0; |
|
-- interconnect signals |
signal s_linki: spw_link_in_type; |
signal s_linko: spw_link_out_type; |
signal s_rxen: std_logic; |
signal s_recvo: spw_recv_out_type; |
signal s_xmiti: spw_xmit_in_type; |
signal s_xmito: spw_xmit_out_type; |
signal s_inact: std_logic; |
signal s_inbvalid: std_logic; |
signal s_inbits: std_logic_vector(rxchunk-1 downto 0); |
|
-- interface signals |
signal rst: std_logic := '1'; |
signal autostart: std_logic; |
signal linkstart: std_logic; |
signal linkdis: std_logic; |
signal divcnt: std_logic_vector(7 downto 0) := (others => '0'); |
signal tick_in: std_logic; |
signal ctrl_in: std_logic_vector(1 downto 0); |
signal time_in: std_logic_vector(5 downto 0); |
signal rxroom: std_logic_vector(5 downto 0); |
signal txwrite: std_logic; |
signal txflag: std_logic; |
signal txdata: std_logic_vector(7 downto 0); |
signal txrdy: std_logic; |
signal tick_out: std_logic; |
signal ctrl_out: std_logic_vector(1 downto 0); |
signal time_out: std_logic_vector(5 downto 0); |
signal rxchar: std_logic; |
signal rxflag: std_logic; |
signal rxdata: std_logic_vector(7 downto 0); |
signal started: std_logic; |
signal connecting:std_logic; |
signal running: std_logic; |
signal errdisc: std_logic; |
signal errpar: std_logic; |
signal erresc: std_logic; |
signal errcred: std_logic; |
signal spw_di: std_logic; |
signal spw_si: std_logic; |
signal spw_do: std_logic; |
signal spw_so: std_logic; |
|
-- misc |
signal errany: std_logic; |
|
procedure print(i: integer) is |
variable v: LINE; |
begin |
write(v, i); |
writeline(output, v); |
end procedure; |
|
procedure print(x: std_logic_vector) is |
variable v: LINE; |
begin |
write(v, to_bitvector(x)); |
writeline(output, v); |
end procedure; |
|
procedure prints(s: string) is |
variable v: LINE; |
begin |
write(v, s); |
writeline(output, v); |
end procedure; |
|
procedure print(lbl: string; x: integer) is |
variable v: LINE; |
begin |
write(v, lbl & " = "); |
write(v, x); |
writeline(output, v); |
end procedure; |
|
procedure print(lbl: string; x: real) is |
variable v: LINE; |
begin |
write(v, lbl & " = "); |
write(v, x); |
writeline(output, v); |
end procedure; |
|
begin |
|
-- Instantiate components. |
|
spwlink_inst: spwlink |
generic map ( |
reset_time => integer(sys_clock_freq * 0.0000064) ) -- 6.4 us |
port map ( |
clk => sysclk, |
rst => rst, |
linki => s_linki, |
linko => s_linko, |
rxen => s_rxen, |
recvo => s_recvo, |
xmiti => s_xmiti, |
xmito => s_xmito ); |
|
spwrecv_inst: spwrecv |
generic map ( |
disconnect_time => integer(sys_clock_freq * 0.00000085), -- 850 ns |
rxchunk => rxchunk ) |
port map ( |
clk => sysclk, |
rxen => s_rxen, |
recvo => s_recvo, |
inact => s_inact, |
inbvalid => s_inbvalid, |
inbits => s_inbits ); |
|
spwxmit_if: if tximpl = impl_generic generate |
spwxmit_inst: spwxmit |
port map ( |
clk => sysclk, |
rst => rst, |
divcnt => divcnt, |
xmiti => s_xmiti, |
xmito => s_xmito, |
spw_so => spw_so, |
spw_do => spw_do ); |
end generate; |
spwxmit_fast_if: if tximpl = impl_fast generate |
spwxmit_fast_inst: spwxmit_fast |
port map ( |
clk => sysclk, |
txclk => txclk, |
rst => rst, |
divcnt => divcnt, |
xmiti => s_xmiti, |
xmito => s_xmito, |
spw_so => spw_so, |
spw_do => spw_do ); |
end generate; |
|
spwrecvfront_generic_if: if rximpl = impl_generic generate |
spwrecvfront_generic_inst: spwrecvfront_generic |
port map ( |
clk => sysclk, |
rxen => s_rxen, |
inact => s_inact, |
inbvalid => s_inbvalid, |
inbits => s_inbits, |
spw_di => spw_di, |
spw_si => spw_si ); |
end generate; |
spwrecvfront_fast_if: if rximpl = impl_fast generate |
spwrecvfront_fast_inst: spwrecvfront_fast |
generic map ( |
rxchunk => rxchunk ) |
port map ( |
clk => sysclk, |
rxclk => rxclk, |
rxen => s_rxen, |
inact => s_inact, |
inbvalid => s_inbvalid, |
inbits => s_inbits, |
spw_di => spw_di, |
spw_si => spw_si ); |
end generate; |
|
s_linki <= ( autostart => autostart, |
linkstart => linkstart, |
linkdis => linkdis, |
rxroom => rxroom, |
tick_in => tick_in, |
ctrl_in => ctrl_in, |
time_in => time_in, |
txwrite => txwrite, |
txflag => txflag, |
txdata => txdata ); |
started <= s_linko.started; |
connecting <= s_linko.connecting; |
running <= s_linko.running; |
errdisc <= s_linko.errdisc; |
errpar <= s_linko.errpar; |
erresc <= s_linko.erresc; |
errcred <= s_linko.errcred; |
txrdy <= s_linko.txack; |
tick_out <= s_linko.tick_out; |
ctrl_out <= s_linko.ctrl_out; |
time_out <= s_linko.time_out; |
rxchar <= s_linko.rxchar; |
rxflag <= s_linko.rxflag; |
rxdata <= s_linko.rxdata; |
|
-- Logic OR of all error signals. |
errany <= errdisc or errpar or erresc or errcred; |
|
-- Generate system clock. |
process is |
begin |
if sys_clock_enable /= '1' then |
wait until sys_clock_enable = '1'; |
end if; |
sysclk <= '1'; |
wait for (0.5 sec) / sys_clock_freq; |
sysclk <= '0'; |
wait for (0.5 sec) / sys_clock_freq; |
end process; |
|
-- Generate rx sample clock. |
process is |
begin |
if sys_clock_enable /= '1' then |
wait until sys_clock_enable = '1'; |
end if; |
rxclk <= '1'; |
wait for (0.5 sec) / rx_clock_freq; |
rxclk <= '0'; |
wait for (0.5 sec) / rx_clock_freq; |
end process; |
|
-- Generate tx clock. |
process is |
begin |
if sys_clock_enable /= '1' then |
wait until sys_clock_enable = '1'; |
end if; |
txclk <= '1'; |
wait for (0.5 sec) / tx_clock_freq; |
txclk <= '0'; |
wait for (0.5 sec) / tx_clock_freq; |
end process; |
|
-- Collect output bits on SPW_DO and SPW_SO. |
process is |
variable t_last: time; |
variable output_last_do: std_logic; |
variable output_last_so: std_logic; |
begin |
if output_collect = '1' then |
-- wait for next bit |
if output_ptr <= output_bits'high then |
output_bits(output_ptr) <= spw_do; |
output_ptr <= output_ptr + 1; |
end if; |
output_last_do := spw_do; |
output_last_so := spw_so; |
t_last := now; |
wait until (output_collect = '0') or (output_last_do /= spw_do) or (output_last_so /= spw_so); |
if output_collect = '1' and output_ptr > 1 then |
assert now > t_last + outbit_period - 1 ns |
report "output bit period too short"; |
assert now < t_last + outbit_period + 1 ns |
report "output bit period too long"; |
end if; |
else |
-- reset |
output_ptr <= 0; |
output_last_do := '0'; |
output_last_so := '0'; |
wait until output_collect = '1'; |
end if; |
end process; |
|
-- Collect received data on rxdata and tick_out. |
process is |
begin |
wait until ((output_collect = '1') and rising_edge(sysclk)) or |
((output_collect = '0') and (output_nchars /= 0)); |
if output_collect = '0' then |
output_nchars <= 0; |
elsif rising_edge(sysclk) and (output_nchars <= output_chars'high) then |
assert (rxchar = '0') or (tick_out = '0'); |
if tick_out = '1' then |
output_chars(output_nchars) <= "10" & ctrl_out & time_out; |
output_nchars <= output_nchars + 1; |
elsif rxchar = '1' then |
output_chars(output_nchars) <= "0" & (rxflag) & rxdata; |
output_nchars <= output_nchars + 1; |
end if; |
end if; |
end process; |
|
-- Generate input data. |
process is |
procedure input_reset is |
begin |
spw_di <= '0'; |
spw_si <= '0'; |
input_par <= '0'; |
end procedure; |
procedure genbit(b: std_logic) is |
begin |
spw_si <= not (spw_si xor spw_di xor b); |
spw_di <= b; |
wait for inbit_period; |
end procedure; |
procedure genfct is |
begin |
genbit(input_par); |
genbit('1'); |
genbit('0'); |
input_par <= '0'; |
genbit('0'); |
end procedure; |
procedure genesc is |
begin |
genbit(input_par); |
genbit('1'); |
genbit('1'); |
input_par <= '0'; |
genbit('1'); |
end procedure; |
procedure geneop(e: std_logic) is |
begin |
genbit(input_par); |
genbit('1'); |
genbit(e); |
input_par <= '1'; |
genbit(not e); |
end procedure; |
procedure gendat(dat: std_logic_vector(7 downto 0)) is |
begin |
genbit(not input_par); |
genbit('0'); |
genbit(dat(0)); genbit(dat(1)); genbit(dat(2)); genbit(dat(3)); |
genbit(dat(4)); genbit(dat(5)); genbit(dat(6)); |
input_par <= dat(0) xor dat(1) xor dat(2) xor dat(3) xor |
dat(4) xor dat(5) xor dat(6) xor dat(7); |
genbit(dat(7)); |
end procedure; |
begin |
input_idle <= '1'; |
input_reset; |
wait until input_pattern /= 0; |
input_idle <= '0'; |
while input_pattern /= 0 loop |
if input_pattern = 1 then |
-- NULL tokens |
genesc; genfct; |
elsif input_pattern = 2 then |
-- FCT tokens |
genfct; |
elsif input_pattern = 3 then |
-- invalid bit pattern |
genbit('0'); |
genbit('1'); |
elsif input_pattern = 4 then |
-- EOP token |
geneop('0'); |
elsif input_pattern = 5 then |
-- FCT, TIME, 8 chars, NULLs |
genfct; |
genesc; gendat("00111000"); |
gendat("01010101"); |
gendat("10101010"); |
gendat("01010101"); |
gendat("10101010"); |
gendat("01010101"); |
gendat("10101010"); |
gendat("01010101"); |
gendat("10101010"); |
while input_pattern = 5 loop |
genesc; genfct; |
end loop; |
elsif input_pattern = 6 then |
-- ESC tokens |
genesc; |
elsif input_pattern = 7 then |
-- FCT, NULL, NULL, EOP, EEP, NULLs |
genfct; |
genesc; genfct; |
genesc; genfct; |
geneop('0'); |
geneop('1'); |
while input_pattern = 7 loop |
genesc; genfct; |
end loop; |
elsif input_pattern = 8 then |
-- FCT, NULL, NULL, NULL, NULL, NULL, char, parity error |
genfct; |
genesc; genfct; |
genesc; genfct; |
genesc; genfct; |
genesc; genfct; |
genesc; genfct; |
gendat("01010101"); |
genbit(not input_par); |
genbit('0'); |
genbit('1'); genbit('0'); genbit('1'); genbit('0'); |
genbit('1'); genbit('0'); genbit('1'); |
input_par <= '1'; -- wrong parity !! |
genbit('0'); |
while input_pattern = 8 loop |
genesc; genfct; |
end loop; |
else |
assert false; |
end if; |
end loop; |
end process; |
|
-- Main process. |
process is |
|
-- Skip NULL tokens and return position of first non-NULL. |
function skip_null(data: in std_logic_vector; start: in integer; len: in integer) return integer is |
variable i: integer; |
begin |
i := start; |
if (i + 7 < len) and (data((i+1) to (i+7)) = "1110100") then |
i := i + 8; |
end if; |
while (i + 7 < len) and (data(i to (i+7)) = "01110100") loop |
i := i + 8; |
end loop; |
return i; |
end function; |
|
function check_parity(data: in std_logic_vector; start: in integer; len: in integer) return boolean is |
variable i: integer; |
variable p: std_logic; |
begin |
i := start; |
p := data(start); |
while i + 3 < len loop |
if data(i+1) = '1' then |
if data(0) /= p then return false; end if; |
p := data(2) xor data(3); |
i := i + 4; |
else |
if i + 9 < len then return true; end if; |
if data(0) /= not p then return false; end if; |
p := not (data(2) xor data(3) xor data(4) xor data(5) xor |
data(6) xor data(7) xor data(8) xor data(9)); |
i := i + 10; |
end if; |
end loop; |
return true; |
end function; |
|
variable i: integer; |
|
begin |
|
-- Wait for start of test. |
wait for startwait; |
|
-- Initialize. |
rst <= '1'; |
input_pattern <= 0; |
sys_clock_enable <= '1'; |
output_collect <= '0'; |
|
-- Say hello |
report "Starting spwlink test bench"; |
print(" sys_clock_freq", sys_clock_freq); |
print(" rx_clock_freq ", rx_clock_freq); |
print(" tx_clock_freq ", tx_clock_freq); |
print(" input_rate ", input_rate); |
print(" tx_clock_div ", tx_clock_div); |
case rximpl is |
when impl_generic => prints(" rximpl = impl_generic"); |
when impl_fast => prints(" rximpl = impl_fast"); |
end case; |
print(" rxchunk ", rxchunk); |
case tximpl is |
when impl_generic => prints(" tximpl = impl_generic"); |
when impl_fast => prints(" tximpl = impl_fast"); |
end case; |
|
-- Test 1: Reset. |
autostart <= '0'; linkstart <= '0'; linkdis <= '0'; |
divcnt <= std_logic_vector(to_unsigned(tx_clock_div, divcnt'length)); |
tick_in <= '0'; ctrl_in <= "00"; time_in <= "000000"; rxroom <= "000000"; |
txwrite <= '0'; txflag <= '0'; txdata <= "00000000"; |
wait until rising_edge(sysclk); |
wait until rising_edge(sysclk); |
wait for 1 ns; |
rst <= '0'; |
assert (txrdy = '0') report " 1. reset (txrdy = 0)"; |
assert (tick_out = '0') report " 1. reset (tick_out = 0)"; |
assert (rxchar = '0') report " 1. reset (rxchar = 0)"; |
assert (started = '0') report " 1. reset (started = 0)"; |
assert (connecting = '0') report " 1. reset (connecting = 0)"; |
assert (running = '0') report " 1. reset (running = 0)"; |
assert (errdisc = '0') report " 1. reset (errdisc = 0)"; |
assert (errpar = '0') report " 1. reset (errpar = 0)"; |
assert (erresc = '0') report " 1. reset (erresc = 0)"; |
assert (errcred = '0') report " 1. reset (errcred = 0)"; |
assert (spw_do = '0') report " 1. reset (spw_do = 0)"; |
assert (spw_so = '0') report " 1. reset (spw_so = 0)"; |
|
-- Test 2: Remain idle after one clock cycle. |
wait until rising_edge(sysclk); |
wait until falling_edge(sysclk); |
assert (started = '0') and (running = '0') |
report " 2. init (state)"; |
assert (spw_do = '0') and (spw_so = '0') |
report " 2. init (SPW idle)"; |
|
-- Test 3: Move to Ready state. |
wait on started, running, spw_do, spw_so for 50 us; |
assert (started = '0') and (running = '0') |
report " 3. ready (state)"; |
assert (spw_do = '0') and (spw_so = '0') |
report " 3. ready (SPW idle)"; |
|
-- Test 4: Start link; wait for NULL patterns. |
linkstart <= '1'; |
rxroom <= "001111"; |
wait on started, connecting, running, spw_do, spw_so for 1 us; |
assert (started = '1') and (running = '0') |
report " 4. nullgen (started)"; |
if spw_so = '0' then |
wait on started, connecting, running, spw_do, spw_so for 1.2 us; |
end if; |
assert (started = '1') and (connecting = '0') and (running = '0') and |
(spw_do = '0') and (spw_so = '1') |
report " 4. nullgen (SPW strobe)"; |
output_collect <= '1'; |
wait on started, connecting, running for (7.1 * outbit_period); |
assert (started = '1') and (running = '0') |
report " 4. nullgen (state 2)"; |
assert (output_ptr = 8) and (output_bits(0 to 7) = "01110100") |
report " 4. nullgen (NULL 1)"; |
-- got the first NULL, wait for the second one ... |
wait on started, connecting, running for (8.0 * outbit_period); |
assert (started = '1') and (running = '0') |
report " 4. nullgen (state 3)"; |
assert (output_ptr = 16) and (output_bits(8 to 15) = "01110100") |
report " 4. nullgen (NULL 2)"; |
output_collect <= '0'; |
|
-- Test 5: Timeout in Started state. |
wait on started, connecting, running, errany for 9.5 us - (15.0 * outbit_period); |
assert (started = '1') and (running = '0') and (errany = '0') |
report " 5. started_timeout (wait)"; |
wait on started, connecting, running, errany for 4 us; |
assert (started = '0') and (connecting = '0') and (running = '0') and (errany = '0') |
report " 5. started_timeout (trigger)"; |
wait for (3.1 * outbit_period + 20 * txclk_period); |
assert (spw_do = '0') and (spw_so = '0') |
report " 5. started_timeout (SPW to zero)"; |
|
-- Test 6: Start link; simulate NULL pattern; wait for FCT pattern. |
wait on started, connecting, running, spw_so for 18 us - (3.1 * outbit_period + 20 * txclk_period); |
assert (started = '0') and (connecting = '0') and (running = '0') and (spw_so = '0') |
report " 6. fctgen (SPW idle)"; |
wait on started, connecting, running, spw_so for 2 us; |
assert (started = '1') and (connecting = '0') and (running = '0') |
report " 6. fctgen (started)"; |
if spw_so = '0' then |
wait on started, connecting, running, spw_do, spw_so for 1.2 us; |
end if; |
assert (spw_do = '0') and (spw_so = '1') |
report " 6. fctgen (SPW strobe)"; |
output_collect <= '1'; |
input_pattern <= 1; |
wait on started, connecting, running for 8 us; |
assert (started = '0') and (connecting = '1') and (running = '0') |
report " 6. fctgen (detect NULL)"; |
wait for (1.1 sec) / sys_clock_freq; |
wait on started, connecting, running, errany for 12 us; |
assert (started = '0') and (connecting = '1') and (running = '0') and (errany = '0') |
report " 6. fctgen (connecting failed early)"; |
assert (output_ptr > 7) and (output_bits(0 to 7) = "01110100") |
report " 6. fctgen (gen NULL)"; |
i := skip_null(output_bits, 0, output_ptr); |
assert (i > 0) and (i + 11 < output_ptr) and (output_bits(i to (i+11)) = "010001110100") |
report " 6. fctgen (gen FCT NULL)"; |
output_collect <= '0'; |
|
-- Test 7: Timeout in Connecting state. |
wait on started, connecting, running, errany for 4 us; |
assert (started = '0') and (connecting = '0') and (running = '0') and (errany = '0') |
report " 7. connecting_timeout"; |
input_pattern <= 0; |
wait until rising_edge(sysclk); |
|
-- Test 8: Autostart link; simulate NULL and FCT; move to Run state; disconnect. |
linkstart <= '0'; |
autostart <= '1'; |
rxroom <= "010000"; |
wait on started, connecting, running, errany for 50 us; |
assert (started = '0') and (connecting = '0') and (running = '0') and (errany = '0') |
report " 8. autostart (wait)"; |
output_collect <= '1'; |
input_pattern <= 1; |
wait on started, connecting, running for 200 ns + 20 * inbit_period; |
assert (started = '1') and (connecting = '0') and (running = '0') |
report " 8. autostart (Started)"; |
input_pattern <= 2; |
wait on started, connecting, running for 1 us; |
assert (started = '0') and (connecting = '1') and (running = '0') |
report " 8. autostart (Connecting)"; |
wait on started, connecting, running, errany for 200 ns + 24 * inbit_period; |
assert (started = '0') and (connecting = '0') and (running = '1') and (errany = '0') |
report " 8. autostart (Run)"; |
input_pattern <= 1; |
txwrite <= '1'; |
if txrdy = '0' then |
wait on running, errany, txrdy for (20 * outbit_period); |
end if; |
assert (running = '1') and (errany = '0') and (txrdy = '1') |
report " 8. running (txrdy = 1)"; |
txwrite <= '0'; |
wait on running, errany for 50 us; |
assert (running = '1') and (errany = '0') |
report " 8. running stable"; |
assert output_bits(1 to 24) = "011101000100010001110100" |
report " 8. NULL FCT FCT NULL"; |
output_collect <= '0'; |
linkdis <= '1'; |
wait on started, running, errany for (2.1 sec) / sys_clock_freq; |
assert (started = '0') and (running = '0') and (errany = '0') |
report " 8. link disable"; |
autostart <= '0'; |
linkdis <= '0'; |
input_pattern <= 0; |
wait until rising_edge(sysclk); |
|
-- Test 9: Start link until Run state; disconnect. |
linkstart <= '1'; |
rxroom <= "001000"; |
input_pattern <= 1; |
wait on started, connecting, running for 20 us; |
assert (started = '1') and (connecting = '0') and (running = '0') |
report " 9. running_disconnect (Started)"; |
linkstart <= '0'; |
wait until rising_edge(sysclk); |
input_pattern <= 2; |
wait on started, connecting, running, errany for 20 * inbit_period; |
assert (started = '0') and (connecting = '1') and (running = '0') and (errany = '0') |
report " 9. running_disconnect (Connecting)"; |
wait on started, connecting, running, errany for 150 ns + 24 * inbit_period; |
assert (started = '0') and (connecting = '0') and (running = '1') and (errany = '0') |
report " 9. running_disconnect (Run)"; |
input_pattern <= 0; |
wait until input_idle = '1'; |
wait on started, connecting, running, errany for 1500 ns; |
assert errdisc = '1' |
report " 9. running_disconnect (errdisc = 1)"; |
if running = '1' then |
wait on started, connecting, running for (1.1 sec) / sys_clock_freq; |
end if; |
assert (started = '0') and (connecting = '0') and (running = '0') |
report " 9. running_disconnect (running = 0)"; |
wait until rising_edge(sysclk); |
assert (started = '0') and (connecting = '0') and (running = '0') and (errany = '0') |
report " 9. running_disconnect (reset)"; |
wait until rising_edge(sysclk); |
|
-- Test 10: Junk signal before starting link. |
autostart <= '1'; |
input_pattern <= 3; |
wait on started, errany for 6 us; |
assert (started = '0') and (errany = '0') |
report "10. junk signal (ignore noise)"; |
input_pattern <= 2; |
wait on started, errany for 4 us; |
assert (started = '0') and (errany = '0') |
report "10. junk signal (ignore FCT)"; |
input_pattern <= 0; |
wait until input_idle = '1'; |
input_pattern <= 1; -- send NULL |
wait until input_idle = '0'; |
input_pattern <= 3; -- send invalid pattern; spw should now reset |
wait on started, errany for 8 us; |
assert (started = '0') and (errany = '0') |
report "10. junk signal (hidden reset)"; |
input_pattern <= 1; -- send NULL |
wait on started, errany for 10 us; |
assert (started = '0') and (errany = '0') |
report "10. junk signal (waiting)"; |
wait on started, errany for 10 us; |
assert (started = '1') and (errany = '0') |
report "10. junk signal (Started)"; |
autostart <= '0'; |
rst <= '1'; |
wait until rising_edge(sysclk); |
rst <= '0'; |
wait until rising_edge(sysclk); |
assert (started = '0') and (errany = '0') |
report "10. junk signal (rst)"; |
wait until rising_edge(sysclk); |
|
-- Test 11: Incoming EOP before first FCT. |
linkstart <= '1'; |
rxroom <= "001000"; |
input_pattern <= 1; |
wait on connecting, running, errany for 21 us; |
assert (connecting = '1') and (errany = '0') |
report "11. unexpected EOP (Connecting)"; |
input_pattern <= 4; |
linkstart <= '0'; |
wait on connecting, running, errany for 200 ns + 24 * inbit_period; |
assert (connecting = '0') and (running = '0') and (errany = '0') |
report "11. unexpected EOP (reset on EOP)"; |
input_pattern <= 0; |
wait for (10 * outbit_period); |
|
-- Test 12: Send and receive characters, time codes, abort on double ESC. |
wait until falling_edge(sysclk); |
linkstart <= '1'; |
wait on started, errany for 21 us; |
assert (started = '1') and (errany = '0') |
report "12. characters (Started)"; |
rxroom <= "001000"; |
input_pattern <= 1; |
output_collect <= '1'; |
tick_in <= '1'; |
wait on connecting, running, errany for 21 us; |
assert (connecting = '1') and (errany = '0') |
report "12. characters (Connecting)"; |
wait until output_ptr > 9 for 2 us; |
input_pattern <= 5; -- FCT, TIME, 8 chars, NULLs |
time_in <= "000111"; |
txwrite <= '1'; |
txflag <= '0'; |
txdata <= "01101100"; |
wait on connecting, running, errany for 200 ns + (24 * inbit_period); |
assert (running = '1') and (errany = '0') |
report "12. characters (Run)"; |
wait until rising_edge(sysclk); |
assert (running = '1') and (errany = '0') |
report "12. characters (running = 1)"; |
tick_in <= '0'; |
wait for 4 * outbit_period; -- wait until first FCT sent |
rxroom <= "000111"; |
wait until txrdy = '1' for 200 ns + (20 * outbit_period); |
assert (running = '1') and (txrdy = '1') |
report "12. characters (txrdy = 1)"; |
wait on running, errany for 50 us + (80 * outbit_period); |
assert (running = '1') and (errany = '0') |
report "12. characters (stable)"; |
input_pattern <= 6; -- just ESC tokens |
wait on running, errany for 200 ns + (32 * inbit_period); |
assert erresc = '1' |
report "12. characters (erresc = 1)"; |
wait until rising_edge(sysclk); |
wait for 1 ns; |
assert (started = '0') and (connecting = '0') and (running = '0') |
report "12. characters (reset)"; |
assert (output_ptr > 8) and (output_bits(1 to 8) = "01110100") |
report "12. characters (gen NULL 1)"; |
i := skip_null(output_bits, 1, output_ptr); |
assert (i > 0) and (output_bits(i to (i+3)) = "0100") |
report "12. characters (gen FCT)"; |
i := skip_null(output_bits, i + 4, output_ptr); |
assert (i + 13 < output_ptr) and (output_bits(i to (i+13)) = "01111011100000") |
report "12. characters (gen TimeCode)"; |
i := i + 14; |
assert (i + 79 < output_ptr) and (output_bits(i to (i+79)) = "00001101101000110110100011011010001101101000110110100011011010001101101000110110") |
report "12. characters (gen Data)"; |
i := i + 80; |
assert (i + 7 < output_ptr) and (output_bits(i to (i+7)) = "01110100") |
report "12. characters (gen NULL 2)"; |
assert (output_nchars > 0) and (output_chars(0) = "1000111000") |
report "12. characters (got TimeCode)"; |
assert (output_nchars > 1) and (output_chars(1) = "0001010101") |
report "12. characters (got byte 1)"; |
assert (output_nchars > 2) and (output_chars(2) = "0010101010") |
report "12. characters (got byte 2)"; |
assert (output_nchars > 3) and (output_chars(3) = "0001010101") |
report "12. characters (got byte 3)"; |
assert (output_nchars > 4) and (output_chars(4) = "0010101010") |
report "12. characters (got byte 4)"; |
assert check_parity(output_bits, 1, output_ptr) |
report "12. parity of output bits"; |
output_collect <= '0'; |
input_pattern <= 0; |
txwrite <= '0'; |
linkstart <= '0'; |
wait for (20 * outbit_period); |
|
-- Test 13: Send and receive EOP, EEP, abort on credit error. |
linkstart <= '1'; |
rxroom <= "001000"; |
input_pattern <= 1; |
output_collect <= '1'; |
wait on connecting, running, errany for 21 us; |
assert (connecting = '1') and (errany = '0') |
report "13. eop, eep (Connecting)"; |
wait until output_ptr > 9 for 2 us; |
input_pattern <= 7; -- FCT, NULL, NULL, EOP, EEP, NULLs |
wait for (1.1 sec) / sys_clock_freq; |
wait on connecting, running, errany for 12 us; |
assert (running = '1') and (errany = '0') |
report "13. eop, eep (Run)"; |
wait for 1 ns; |
txwrite <= '1'; |
txflag <= '1'; |
txdata <= "01101100"; |
wait until rising_edge(sysclk) and txrdy = '1' for 1 us + (14 * outbit_period); |
assert (txrdy = '1') and (running = '1') and (errany = '0') |
report "13. eop, eep (txrdy 1)"; |
rxroom <= "000111" after 1 ns; |
txdata <= "00000001" after 1 ns; |
wait until rising_edge(sysclk) and txrdy = '1' for 1 us + (14 * outbit_period); |
assert (txrdy = '1') and (running = '1') and (errany = '0') |
report "13. eop, eep (txrdy 2)"; |
txdata <= "00000000" after 1 ns; |
wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period); |
assert (txrdy = '1') and (running = '1') and (errany = '0') |
report "13. eop, eep (txrdy 3)"; |
txdata <= "11111111" after 1 ns; |
wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period); |
assert (txrdy = '1') and (running = '1') and (errany = '0') |
report "13. eop, eep (txrdy 4)"; |
txdata <= "11111110" after 1 ns; |
wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period); |
assert (txrdy = '1') and (running = '1') and (errany = '0') |
report "13. eop, eep (txrdy 5)"; |
txdata <= "01010101" after 1 ns; |
wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period); |
assert (txrdy = '1') and (running = '1') and (errany = '0') |
report "13. eop, eep (txrdy 6)"; |
txdata <= "10101010" after 1 ns; |
wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period); |
assert (txrdy = '1') and (running = '1') and (errany = '0') |
report "13. eop, eep (txrdy 7)"; |
txdata <= "01010101" after 1 ns; |
wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period); |
assert (txrdy = '1') and (running = '1') and (errany = '0') |
report "13. eop, eep (txrdy 8)"; |
txdata <= "10101010" after 1 ns; |
wait until rising_edge(sysclk) and (txrdy = '1') for (14 * outbit_period); |
assert (txrdy = '0') and (running = '1') and (errany = '0') |
report "13. eop, eep (txrdy 9)"; |
txwrite <= '0'; |
txflag <= '0'; |
wait on running, errany for (10 * outbit_period); |
assert (running = '1') and (errany = '0') |
report "13. eop, eep (flush out)"; |
input_pattern <= 2; -- FCT tokens |
wait on running, errany for (80 * inbit_period); |
assert errcred = '1' |
report "13. eop, eep (errcred = 1)"; |
wait until running = '0'; |
assert (output_ptr > 8) and (output_bits(1 to 8) = "01110100") |
report "13. eop, eep (gen NULL 1)"; |
i := skip_null(output_bits, 1, output_ptr); |
assert (i > 0) and (output_bits(i to (i+3)) = "0100") |
report "13. eop, eep (gen FCT)"; |
i := i + 4; |
for j in 0 to 3 loop |
i := skip_null(output_bits, i, output_ptr); |
assert (i + 3 < output_ptr) and (output_bits(i+1 to (i+3)) = "101") |
report "13. eop, eep (eop)"; |
i := skip_null(output_bits, i + 4, output_ptr); |
assert (i + 3 < output_ptr) and (output_bits(i+1 to (i+3)) = "110") |
report "13. eop, eep (eep)"; |
i := i + 4; |
end loop; |
assert (i + 8 < output_ptr) and (output_bits(i to (i+8)) = "111101000") |
report "13. eop, eep (gen NULL 2)"; |
assert check_parity(output_bits, 1, output_ptr) |
report "12. parity of output bits"; |
assert (output_nchars > 0) and (output_chars(0) = "0100000000") |
report "13. eop, eep (got EOP)"; |
assert (output_nchars = 2) and (output_chars(1) = "0100000001") |
report "13. eop, eep (got EEP)"; |
output_collect <= '0'; |
input_pattern <= 0; |
linkstart <= '0'; |
wait until rising_edge(sysclk); |
|
-- Test 14: Abort on parity error. |
wait for 10 us; |
assert spw_do = '0' and spw_so = '0' |
report "14. output still babbling"; |
linkstart <= '1'; |
rxroom <= "001000"; |
input_pattern <= 1; |
output_collect <= '1'; |
wait for 1 ns; -- ghdl is totally fucked up |
wait on connecting, running, errany for 21 us; |
assert (connecting = '1') and (errany = '0') |
report "14. partity (Connecting)"; |
input_pattern <= 8; -- FCT, NULL, NULL, NULL, NULL, NULL, char, error |
wait for (1.1 sec) / sys_clock_freq; |
wait on running, errany for 12 us; |
assert (running = '1') and (errany = '0') |
report "14. parity (Run)"; |
wait on running, errany for 150 ns + (84 * inbit_period); |
assert errpar = '1' |
report "14. parity (errpar = 1)"; |
wait until running = '0'; |
assert (output_nchars = 1) and (output_chars(0) = "0001010101") |
report "14. parity (received char)"; |
output_collect <= '0'; |
input_pattern <= 0; |
linkstart <= '0'; |
wait until rising_edge(sysclk); |
|
-- Stop simulation |
input_pattern <= 0; |
wait for 100 us; |
sys_clock_enable <= '0'; |
report "Done."; |
wait; |
|
end process; |
|
end tb_arch; |
/GPL-2.txt
0,0 → 1,339
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc., |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
|
Preamble |
|
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Lesser General Public License instead.) You can apply it to |
your programs, too. |
|
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
|
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
|
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
|
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
|
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
|
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
|
The precise terms and conditions for copying, distribution and |
modification follow. |
|
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
|
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
|
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
|
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
|
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
|
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
|
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
|
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
|
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
|
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
|
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
|
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
|
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
|
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
|
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
|
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
|
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
|
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
|
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
|
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
|
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
|
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
|
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
|
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
|
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
|
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
|
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
|
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
|
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
|
NO WARRANTY |
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
|
END OF TERMS AND CONDITIONS |
|
How to Apply These Terms to Your New Programs |
|
If you develop a new program, and you want it to be of the greatest |
possible use to the public, the best way to achieve this is to make it |
free software which everyone can redistribute and change under these terms. |
|
To do so, attach the following notices to the program. It is safest |
to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least |
the "copyright" line and a pointer to where the full notice is found. |
|
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) <year> <name of author> |
|
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License along |
with this program; if not, write to the Free Software Foundation, Inc., |
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|
Also add information on how to contact you by electronic and paper mail. |
|
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
|
Gnomovision version 69, Copyright (C) year name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
|
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
|
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
|
<signature of Ty Coon>, 1 April 1989 |
Ty Coon, President of Vice |
|
This General Public License does not permit incorporating your program into |
proprietary programs. If your program is a subroutine library, you may |
consider it more useful to permit linking proprietary applications with the |
library. If this is what you want to do, use the GNU Lesser General |
Public License instead of this License. |
/rtl/vhdl/spwrecvfront_fast.vhd
0,0 → 1,467
-- |
-- Front-end for SpaceWire Receiver |
-- |
-- This entity samples the input signals DataIn and StrobeIn to detect |
-- valid bit transitions. Received bits are handed to the application |
-- in groups of "rxchunk" bits at a time, synchronous to the system clock. |
-- |
-- This receiver is based on synchronous oversampling of the input signals. |
-- Inputs are sampled on the rising and falling edges of an externally |
-- supplied sample clock "rxclk". Therefore the maximum bitrate of the |
-- incoming signal must be significantly lower than two times the "rxclk" |
-- clock frequency. The maximum incoming bitrate must also be strictly |
-- lower than rxchunk times the system clock frequency. |
-- |
-- This code is tuned for implementation on Xilinx Spartan-3. |
-- |
-- Details |
-- ------- |
-- |
-- Stage A: The inputs "spw_di" and "spw_si" are handled as DDR signals, |
-- synchronously sampled on both edges of "rxclk". |
-- |
-- Stage B: The input signals are re-registered on the rising edge of "rxclk" |
-- for further processing. This implies that every rising edge of "rxclk" |
-- produces two new samples of "spw_di" and two new samples of "spw_si". |
-- Some preparation is done for data/strobe decoding. |
-- |
-- Stage C: Transitions in input signals are detected by comparing the XOR |
-- of data and strobe to the XOR of the previous data and strobe samples. |
-- If there is a difference, we know that either data or strobe has changed |
-- and the new value of data is a valid new bit. Every rising edge of "rxclk" |
-- thus produces either zero, one or two new data bits. |
-- |
-- Received data bits are pushed into a cyclic buffer. A two-hot array marks |
-- the two positions where the next received bits will go into the buffer. |
-- In addition, a 4-step gray-encoded counter "headptr" indicates the current |
-- position in the cyclic buffer. |
-- |
-- The contents of the cyclic buffer and the head pointer are re-registered |
-- on the rising edge of the system clock. A binary counter "tailptr" points |
-- to next group of bits to read from the cyclic buffer. A comparison between |
-- "tailptr" and "headptr" determines whether those bits have already been |
-- received and safely stored in the buffer. |
-- |
-- Implementation guidelines |
-- ------------------------- |
-- |
-- IOB flip-flops must be used to sample spw_di and spw_si. |
-- Clock skew between the IOBs for spw_di and spw_si must be minimized. |
-- |
-- "rxclk" must be at least as fast as the system clock; |
-- "rxclk" does not need to be phase-related to the system clock; |
-- it is allowed for "rxclk" to be equal to the system clock. |
-- |
-- The following timing constraints are needed: |
-- * PERIOD constraint on the system clock; |
-- * PERIOD constraint on "rxclk"; |
-- * FROM-TO constraint from "rxclk" to system clock, equal to one "rxclk" period; |
-- * FROM-TO constraint from system clock to "rxclk", equal to one "rxclk" period. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity spwrecvfront_fast is |
|
generic ( |
-- Number of bits to pass to the application per system clock. |
rxchunk: integer range 1 to 4 ); |
|
port ( |
-- System clock. |
clk: in std_logic; |
|
-- Sample clock. |
rxclk: in std_logic; |
|
-- High to enable receiver; low to disable and reset receiver. |
rxen: in std_logic; |
|
-- High if there has been recent activity on the input lines. |
inact: out std_logic; |
|
-- High if inbits contains a valid group of received bits. |
-- If inbvalid='1', the application must sample inbits on |
-- the rising edge of clk. |
inbvalid: out std_logic; |
|
-- Received bits (bit 0 is the earliest received bit). |
inbits: out std_logic_vector(rxchunk-1 downto 0); |
|
-- Data In signal from SpaceWire bus. |
spw_di: in std_logic; |
|
-- Strobe In signal from SpaceWire bus. |
spw_si: in std_logic ); |
|
-- Turn off FSM extraction. |
-- Without this, XST will happily apply one-hot encoding to rrx.headptr. |
attribute FSM_EXTRACT: string; |
attribute FSM_EXTRACT of spwrecvfront_fast: entity is "NO"; |
|
-- Turn off register replication. |
-- Without this, XST will happily replicate my synchronization flip-flops. |
attribute REGISTER_DUPLICATION: string; |
attribute REGISTER_DUPLICATION of spwrecvfront_fast: entity is "FALSE"; |
|
end entity spwrecvfront_fast; |
|
architecture spwrecvfront_arch of spwrecvfront_fast is |
|
-- size of the cyclic buffer in bits; |
-- typically 4 times rxchunk, except when rxchunk = 1 |
type chunk_array_type is array(1 to 4) of integer; |
constant chunk_to_buflen: chunk_array_type := ( 8, 8, 12, 16 ); |
constant c_buflen: integer := chunk_to_buflen(rxchunk); |
|
-- convert from straight binary to reflected binary gray code |
function gray_encode(b: in std_logic_vector) return std_logic_vector is |
variable g: std_logic_vector(b'high downto b'low); |
begin |
g(b'high) := b(b'high); |
for i in b'high-1 downto b'low loop |
g(i) := b(i) xor b(i+1); |
end loop; |
return g; |
end function; |
|
-- convert from reflected binary gray code to straight binary |
function gray_decode(g: in std_logic_vector) return std_logic_vector is |
variable b: std_logic_vector(g'high downto g'low); |
begin |
b(g'high) := g(g'high); |
for i in g'high-1 downto g'low loop |
b(i) := g(i) xor b(i+1); |
end loop; |
return b; |
end function; |
|
-- stage A: input flip-flops for rising/falling rxclk |
signal s_a_di0: std_logic; |
signal s_a_di1: std_logic; |
signal s_a_si0: std_logic; |
signal s_a_si1: std_logic; |
|
-- registers in rxclk domain |
type rxregs_type is record |
-- reset synchronizer |
reset: std_logic_vector(1 downto 0); |
-- stage B: re-register input samples and prepare for data/strobe decoding |
b_di0: std_ulogic; |
b_di1: std_ulogic; |
b_si1: std_ulogic; |
b_xor0: std_ulogic; -- b_xor0 = b_di0 xor b_si0 |
-- stage C: after data/strobe decoding |
c_bit: std_logic_vector(1 downto 0); |
c_val: std_logic_vector(1 downto 0); |
c_xor1: std_ulogic; |
-- cyclic bit buffer |
bufdata: std_logic_vector(c_buflen-1 downto 0); -- data bits |
bufmark: std_logic_vector(c_buflen-1 downto 0); -- two-hot, marking destination of next two bits |
headptr: std_logic_vector(1 downto 0); -- gray encoded head position |
headlow: std_logic_vector(1 downto 0); -- least significant bits of head position |
headinc: std_ulogic; -- must update headptr on next clock |
-- activity detection |
bitcnt: std_logic_vector(2 downto 0); -- gray counter |
end record; |
|
-- registers in system clock domain |
type regs_type is record |
-- cyclic bit buffer, re-registered to the system clock |
bufdata: std_logic_vector(c_buflen-1 downto 0); -- data bits |
headptr: std_logic_vector(1 downto 0); -- gray encoded head position |
-- tail pointer (binary) |
tailptr: std_logic_vector(2 downto 0); |
-- activity detection |
bitcnt: std_logic_vector(2 downto 0); |
bitcntp: std_logic_vector(2 downto 0); |
bitcntpp: std_logic_vector(2 downto 0); |
-- output registers |
inact: std_ulogic; |
inbvalid: std_ulogic; |
inbits: std_logic_vector(rxchunk-1 downto 0); |
rxen: std_ulogic; |
end record; |
|
-- registers |
signal r, rin: regs_type; |
signal rrx, rrxin: rxregs_type; |
|
-- force use of IOB flip-flops |
attribute IOB: string; |
attribute IOB of s_a_di0: signal is "TRUE"; |
attribute IOB of s_a_di1: signal is "TRUE"; |
attribute IOB of s_a_si0: signal is "TRUE"; |
attribute IOB of s_a_si1: signal is "TRUE"; |
|
begin |
|
-- sample inputs on rising edge of rxclk |
process (rxclk) is |
begin |
if rising_edge(rxclk) then |
s_a_di0 <= spw_di; |
s_a_si0 <= spw_si; |
end if; |
end process; |
|
-- sample inputs on falling edge of rxclk |
process (rxclk) is |
begin |
if falling_edge(rxclk) then |
s_a_di1 <= spw_di; |
s_a_si1 <= spw_si; |
end if; |
end process; |
|
-- combinatorial process |
process (r, rrx, rxen, s_a_di0, s_a_di1, s_a_si0, s_a_si1) |
variable v: regs_type; |
variable vrx: rxregs_type; |
variable v_i: integer range 0 to 7; |
variable v_tail: std_logic_vector(1 downto 0); |
begin |
v := r; |
vrx := rrx; |
v_i := 0; |
v_tail := (others => '0'); |
|
-- ---- SAMPLE CLOCK DOMAIN ---- |
|
-- stage B: re-register input samples |
vrx.b_di0 := s_a_di0; |
vrx.b_di1 := s_a_di1; |
vrx.b_xor0 := s_a_di0 xor s_a_si0; |
vrx.b_si1 := s_a_si1; |
|
-- stage C: decode data/strobe and detect valid bits |
if (rrx.b_xor0 xor rrx.c_xor1) = '1' then |
-- b_di0 is a valid new bit |
vrx.c_bit(0) := rrx.b_di0; |
else |
-- skip b_di0 and try b_di1 |
vrx.c_bit(0) := rrx.b_di1; |
end if; |
vrx.c_bit(1) := rrx.b_di1; |
vrx.c_val(0) := (rrx.b_xor0 xor rrx.c_xor1) or (rrx.b_di1 xor rrx.b_si1 xor rrx.b_xor0); |
vrx.c_val(1) := (rrx.b_xor0 xor rrx.c_xor1) and (rrx.b_di1 xor rrx.b_si1 xor rrx.b_xor0); |
vrx.c_xor1 := rrx.b_di1 xor rrx.b_si1; |
|
-- Note: |
-- c_val = "00" if no new bits are received |
-- c_val = "01" if one new bit is received; the new bit is in c_bit(0) |
-- c_val = "11" if two new bits are received |
|
-- Note: |
-- bufmark contains two '1' bits in neighbouring positions, marking |
-- the positions that newly received bits will be written to. |
|
-- Update the cyclic buffer. |
for i in 0 to c_buflen-1 loop |
-- update data bit at position (i) |
if rrx.bufmark(i) = '1' then |
if rrx.bufmark((i+1) mod rrx.bufmark'length) = '1' then |
-- this is the first of the two marked positions; |
-- put the first received bit here (if any) |
vrx.bufdata(i) := rrx.c_bit(0); |
else |
-- this is the second of the two marked positions; |
-- put the second received bit here (if any) |
vrx.bufdata(i) := rrx.c_bit(1); |
end if; |
end if; |
-- update marker at position (i) |
if rrx.c_val(0) = '1' then |
if rrx.c_val(1) = '1' then |
-- shift two positions |
vrx.bufmark(i) := rrx.bufmark((i+rrx.bufmark'length-2) mod rrx.bufmark'length); |
else |
-- shift one position |
vrx.bufmark(i) := rrx.bufmark((i+rrx.bufmark'length-1) mod rrx.bufmark'length); |
end if; |
end if; |
end loop; |
|
-- Update "headlow", the least significant bits of the head position. |
-- This is a binary counter from 0 to rxchunk-1, or from 0 to 1 |
-- if rxchunk = 1. If the counter overflows, "headptr" will be |
-- updated in the next clock cycle. |
case rxchunk is |
when 1 | 2 => |
-- count from "00" to "01" |
if rrx.c_val(1) = '1' then -- got two new bits |
vrx.headlow(0) := rrx.headlow(0); |
vrx.headinc := '1'; |
elsif rrx.c_val(0) = '1' then -- got one new bit |
vrx.headlow(0) := not rrx.headlow(0); |
vrx.headinc := rrx.headlow(0); |
else -- got nothing |
vrx.headlow(0) := rrx.headlow(0); |
vrx.headinc := '0'; |
end if; |
when 3 => |
-- count from "00" to "10" |
if rrx.c_val(1) = '1' then -- got two new bits |
case rrx.headlow is |
when "00" => vrx.headlow := "10"; |
when "01" => vrx.headlow := "00"; |
when others => vrx.headlow := "01"; |
end case; |
vrx.headinc := rrx.headlow(0) or rrx.headlow(1); |
elsif rrx.c_val(0) = '1' then -- got one new bit |
if rrx.headlow(1) = '1' then |
vrx.headlow := "00"; |
vrx.headinc := '1'; |
else |
vrx.headlow(0) := not rrx.headlow(0); |
vrx.headlow(1) := rrx.headlow(0); |
vrx.headinc := '0'; |
end if; |
else -- got nothing |
vrx.headlow := rrx.headlow; |
vrx.headinc := '0'; |
end if; |
when 4 => |
-- count from "00" to "11" |
if rrx.c_val(1) = '1' then -- got two new bits |
vrx.headlow(0) := rrx.headlow(0); |
vrx.headlow(1) := not rrx.headlow(1); |
vrx.headinc := rrx.headlow(1); |
elsif rrx.c_val(0) = '1' then -- got one new bit |
vrx.headlow(0) := not rrx.headlow(0); |
vrx.headlow(1) := rrx.headlow(1) xor rrx.headlow(0); |
vrx.headinc := rrx.headlow(0) and rrx.headlow(1); |
else -- got nothing |
vrx.headlow := rrx.headlow; |
vrx.headinc := '0'; |
end if; |
end case; |
|
-- Update the gray-encoded head position. |
if rrx.headinc = '1' then |
case rrx.headptr is |
when "00" => vrx.headptr := "01"; |
when "01" => vrx.headptr := "11"; |
when "11" => vrx.headptr := "10"; |
when others => vrx.headptr := "00"; |
end case; |
end if; |
|
-- Activity detection. |
if rrx.c_val(0) = '1' then |
vrx.bitcnt := gray_encode( |
std_logic_vector(unsigned(gray_decode(rrx.bitcnt)) + 1)); |
end if; |
|
-- Synchronize reset signal for rxclk domain. |
if r.rxen = '0' then |
vrx.reset := "11"; |
else |
vrx.reset := "0" & rrx.reset(1); |
end if; |
|
-- Synchronous reset of rxclk domain. |
if rrx.reset(0) = '1' then |
vrx.bufmark := (0 => '1', 1 => '1', others => '0'); |
vrx.headptr := "00"; |
vrx.headlow := "00"; |
vrx.headinc := '0'; |
vrx.bitcnt := "000"; |
end if; |
|
-- ---- SYSTEM CLOCK DOMAIN ---- |
|
-- Re-register cyclic buffer and head pointer in the system clock domain. |
v.bufdata := rrx.bufdata; |
v.headptr := rrx.headptr; |
|
-- Increment tailptr if there was new data on the previous clock. |
if r.inbvalid = '1' then |
v.tailptr := std_logic_vector(unsigned(r.tailptr) + 1); |
end if; |
|
-- Compare tailptr to headptr to decide whether there is new data. |
-- If the values are equal, we are about to read data which were not |
-- yet released by the rxclk domain |
-- Note: headptr is gray-coded while tailptr is normal binary. |
if rxchunk = 1 then |
-- headptr counts blocks of 2 bits while tailptr counts single bits |
v_tail := v.tailptr(2 downto 1); |
else |
-- headptr and tailptr both count blocks of rxchunk bits |
v_tail := v.tailptr(1 downto 0); |
end if; |
if (r.headptr(1) = v_tail(1)) and |
((r.headptr(0) xor r.headptr(1)) = v_tail(0)) then |
-- pointers have the same value |
v.inbvalid := '0'; |
else |
v.inbvalid := '1'; |
end if; |
|
-- Multiplex bits from the cyclic buffer into the output register. |
if rxen = '1' then |
if rxchunk = 1 then |
-- cyclic buffer contains 8 slots of 1 bit wide |
v_i := to_integer(unsigned(v.tailptr)); |
v.inbits := r.bufdata(v_i downto v_i); |
else |
-- cyclic buffer contains 4 slots of rxchunk bits wide |
v_i := to_integer(unsigned(v.tailptr(1 downto 0))); |
v.inbits := r.bufdata(rxchunk*v_i+rxchunk-1 downto rxchunk*v_i); |
end if; |
end if; |
|
-- Activity detection. |
v.bitcnt := rrx.bitcnt; |
v.bitcntp := r.bitcnt; |
v.bitcntpp := r.bitcntp; |
if rxen = '1' then |
if r.bitcntp = r.bitcntpp then |
v.inact := r.inbvalid; |
else |
v.inact := '1'; |
end if; |
end if; |
|
-- Synchronous reset of system clock domain. |
if rxen = '0' then |
v.tailptr := "000"; |
v.inact := '0'; |
v.inbvalid := '0'; |
v.inbits := (others => '0'); |
end if; |
|
-- Register rxen to ensure glitch-free signal to rxclk domain |
v.rxen := rxen; |
|
-- drive outputs |
inact <= r.inact; |
inbvalid <= r.inbvalid; |
inbits <= r.inbits; |
|
-- update registers |
rrxin <= vrx; |
rin <= v; |
|
end process; |
|
-- update registers on rising edge of rxclk |
process (rxclk) is |
begin |
if rising_edge(rxclk) then |
rrx <= rrxin; |
end if; |
end process; |
|
-- update registers on rising edge of system clock |
process (clk) is |
begin |
if rising_edge(clk) then |
r <= rin; |
end if; |
end process; |
|
end architecture spwrecvfront_arch; |
/rtl/vhdl/spwstream.vhd
0,0 → 1,544
-- |
-- SpaceWire core with character-stream interface. |
-- |
-- This entity provides a SpaceWire core with a character-stream interface. |
-- The interface provides means for connection initiation, sending and |
-- receiving of N-Chars and TimeCodes, and error reporting. |
-- |
-- This entity instantiates spwlink, spwrecv, spwxmit and one of the |
-- spwrecvfront implementations. It also implements a receive FIFO and |
-- a transmit FIFO. |
-- |
-- The SpaceWire standard requires that each transceiver use an initial |
-- signalling rate of 10 Mbit/s. This implies that the system clock frequency |
-- must be a multiple of 10 MHz. See the datasheet for further details on |
-- bitrates and clocking. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.spwpkg.all; |
|
entity spwstream is |
|
generic ( |
-- System clock frequency in Hz. |
-- This must be set to the frequency of "clk". It is used to setup |
-- counters for reset timing, disconnect timeout and to transmit |
-- at 10 Mbit/s during the handshake. |
sysfreq: real; |
|
-- Selection of a receiver front-end implementation. |
rximpl: spw_implementation_type := impl_generic; |
|
-- Maximum number of bits received per system clock |
-- (must be 1 in case of impl_generic). |
rxchunk: integer range 1 to 4 := 1; |
|
-- Selection of a transmitter implementation. |
tximpl: spw_implementation_type := impl_generic; |
|
-- Size of the receive FIFO as the 2-logarithm of the number of bytes. |
-- Must be at least 6 (64 bytes). |
rxfifosize_bits: integer range 6 to 14 := 11; |
|
-- Size of the transmit FIFO as the 2-logarithm of the number of bytes. |
txfifosize_bits: integer range 2 to 14 := 11 |
); |
|
port ( |
-- System clock. |
clk: in std_logic; |
|
-- Receiver sample clock (only for impl_fast) |
rxclk: in std_logic; |
|
-- Transmit clock (only for impl_fast) |
txclk: in std_logic; |
|
-- Synchronous reset (active-high). |
rst: in std_logic; |
|
-- Enables automatic link start on receipt of a NULL character. |
autostart: in std_logic; |
|
-- Enables link start once the Ready state is reached. |
-- Without autostart or linkstart, the link remains in state Ready. |
linkstart: in std_logic; |
|
-- Do not start link (overrides linkstart and autostart) and/or disconnect |
-- if the link is in state Run. |
linkdis: in std_logic; |
|
-- Scaling factor minus 1, used to scale the system clock into the transmission |
-- signalling rate. The system clock is divided by (unsigned(divcnt) + 1). |
-- Changing this signal will immediately change the transmission rate. |
-- During link setup, the transmission rate is always 10 Mbit/s. |
txdivcnt: in std_logic_vector(7 downto 0); |
|
-- High for one clock cycle to request transmission of a TimeCode. |
-- The request is registered inside the entity until it can be processed. |
tick_in: in std_logic; |
|
-- Control bits of the TimeCode to be sent. Must be valid while tick_in is high. |
ctrl_in: in std_logic_vector(1 downto 0); |
|
-- Counter value of the TimeCode to be sent. Must be valid while tick_in is high. |
time_in: in std_logic_vector(5 downto 0); |
|
-- Pulled high by the application to write an N-Char to the transmit |
-- queue. If "txwrite" and "txrdy" are both high on the rising edge |
-- of "clk", a character is added to the transmit queue. |
-- This signal has no effect if "txrdy" is low. |
txwrite: in std_logic; |
|
-- Control flag to be sent with the next N_Char. |
-- Must be valid while txwrite is high. |
txflag: in std_logic; |
|
-- Byte to be sent, or "00000000" for EOP or "00000001" for EEP. |
-- Must be valid while txwrite is high. |
txdata: in std_logic_vector(7 downto 0); |
|
-- High if the entity is ready to accept an N-Char for transmission. |
txrdy: out std_logic; |
|
-- High if the transmission queue is at least half full. |
txhalff: out std_logic; |
|
-- High for one clock cycle if a TimeCode was just received. |
tick_out: out std_logic; |
|
-- Control bits of the last received TimeCode. |
ctrl_out: out std_logic_vector(1 downto 0); |
|
-- Counter value of the last received TimeCode. |
time_out: out std_logic_vector(5 downto 0); |
|
-- High if "rxflag" and "rxdata" contain valid data. |
-- This signal is high unless the receive FIFO is empty. |
rxvalid: out std_logic; |
|
-- High if the receive FIFO is at least half full. |
rxhalff: out std_logic; |
|
-- High if the received character is EOP or EEP; low if the received |
-- character is a data byte. Valid if "rxvalid" is high. |
rxflag: out std_logic; |
|
-- Received byte, or "00000000" for EOP or "00000001" for EEP. |
-- Valid if "rxvalid" is high. |
rxdata: out std_logic_vector(7 downto 0); |
|
-- Pulled high by the application to accept a received character. |
-- If "rxvalid" and "rxread" are both high on the rising edge of "clk", |
-- a character is removed from the receive FIFO and "rxvalid", "rxflag" |
-- and "rxdata" are updated. |
-- This signal has no effect if "rxvalid" is low. |
rxread: in std_logic; |
|
-- High if the link state machine is currently in the Started state. |
started: out std_logic; |
|
-- High if the link state machine is currently in the Connecting state. |
connecting: out std_logic; |
|
-- High if the link state machine is currently in the Run state, indicating |
-- that the link is fully operational. If none of started, connecting or running |
-- is high, the link is in an initial state and the transmitter is not yet enabled. |
running: out std_logic; |
|
-- Disconnect detected in state Run. Triggers a reset and reconnect of the link. |
-- This indication is auto-clearing. |
errdisc: out std_logic; |
|
-- Parity error detected in state Run. Triggers a reset and reconnect of the link. |
-- This indication is auto-clearing. |
errpar: out std_logic; |
|
-- Invalid escape sequence detected in state Run. Triggers a reset and reconnect of |
-- the link. This indication is auto-clearing. |
erresc: out std_logic; |
|
-- Credit error detected. Triggers a reset and reconnect of the link. |
-- This indication is auto-clearing. |
errcred: out std_logic; |
|
-- Data In signal from SpaceWire bus. |
spw_di: in std_logic; |
|
-- Strobe In signal from SpaceWire bus. |
spw_si: in std_logic; |
|
-- Data Out signal to SpaceWire bus. |
spw_do: out std_logic; |
|
-- Strobe Out signal to SpaceWire bus. |
spw_so: out std_logic |
); |
|
end entity spwstream; |
|
architecture spwstream_arch of spwstream is |
|
-- Convert boolean to std_logic. |
type bool_to_logic_type is array(boolean) of std_ulogic; |
constant bool_to_logic: bool_to_logic_type := (false => '0', true => '1'); |
|
-- Reset time (6.4 us) in system clocks |
constant reset_time: integer := integer(sysfreq * 6.4e-6); |
|
-- Disconnect time (850 ns) in system clocks |
constant disconnect_time: integer := integer(sysfreq * 850.0e-9); |
|
-- Initial tx clock scaler (10 Mbit). |
constant default_divcnt: std_logic_vector(7 downto 0) := |
std_logic_vector(to_unsigned(integer(sysfreq / 10.0e6 - 1.0), 8)); |
|
-- Registers. |
type regs_type is record |
-- packet state |
rxpacket: std_logic; -- '1' when receiving a packet |
rxeep: std_logic; -- '1' when rx EEP character pending |
txpacket: std_logic; -- '1' when transmitting a packet |
txdiscard: std_logic; -- '1' when discarding a tx packet |
-- FIFO pointers |
rxfifo_raddr: std_logic_vector(rxfifosize_bits-1 downto 0); |
rxfifo_waddr: std_logic_vector(rxfifosize_bits-1 downto 0); |
txfifo_raddr: std_logic_vector(txfifosize_bits-1 downto 0); |
txfifo_waddr: std_logic_vector(txfifosize_bits-1 downto 0); |
-- FIFO state |
rxfifo_rvalid: std_logic; -- '1' if s_rxfifo_rdata is valid |
txfifo_rvalid: std_logic; -- '1' if s_txfifo_rdata is valid |
rxfull: std_logic; -- '1' if RX fifo is full |
rxhalff: std_logic; -- '1' if RX fifo is at least half full |
txfull: std_logic; -- '1' if TX fifo is full |
txhalff: std_logic; -- '1' if TX fifo is at least half full |
rxroom: std_logic_vector(5 downto 0); |
end record; |
|
constant regs_reset: regs_type := ( |
rxpacket => '0', |
rxeep => '0', |
txpacket => '0', |
txdiscard => '0', |
rxfifo_raddr => (others => '0'), |
rxfifo_waddr => (others => '0'), |
txfifo_raddr => (others => '0'), |
txfifo_waddr => (others => '0'), |
rxfifo_rvalid => '0', |
txfifo_rvalid => '0', |
rxfull => '0', |
rxhalff => '0', |
txfull => '0', |
txhalff => '0', |
rxroom => (others => '0') ); |
|
signal r: regs_type := regs_reset; |
signal rin: regs_type; |
|
-- Interface signals to components. |
signal recv_rxen: std_logic; |
signal recvo: spw_recv_out_type; |
signal recv_inact: std_logic; |
signal recv_inbvalid: std_logic; |
signal recv_inbits: std_logic_vector(rxchunk-1 downto 0); |
signal xmiti: spw_xmit_in_type; |
signal xmito: spw_xmit_out_type; |
signal xmit_divcnt: std_logic_vector(7 downto 0); |
signal linki: spw_link_in_type; |
signal linko: spw_link_out_type; |
|
-- Memory interface signals. |
signal s_rxfifo_raddr: std_logic_vector(rxfifosize_bits-1 downto 0); |
signal s_rxfifo_rdata: std_logic_vector(8 downto 0); |
signal s_rxfifo_wen: std_logic; |
signal s_rxfifo_waddr: std_logic_vector(rxfifosize_bits-1 downto 0); |
signal s_rxfifo_wdata: std_logic_vector(8 downto 0); |
signal s_txfifo_raddr: std_logic_vector(txfifosize_bits-1 downto 0); |
signal s_txfifo_rdata: std_logic_vector(8 downto 0); |
signal s_txfifo_wen: std_logic; |
signal s_txfifo_waddr: std_logic_vector(txfifosize_bits-1 downto 0); |
signal s_txfifo_wdata: std_logic_vector(8 downto 0); |
|
begin |
|
-- Instantiate link controller. |
link_inst: spwlink |
generic map ( |
reset_time => reset_time ) |
port map ( |
clk => clk, |
rst => rst, |
linki => linki, |
linko => linko, |
rxen => recv_rxen, |
recvo => recvo, |
xmiti => xmiti, |
xmito => xmito ); |
|
-- Instantiate receiver. |
recv_inst: spwrecv |
generic map( |
disconnect_time => disconnect_time, |
rxchunk => rxchunk ) |
port map ( |
clk => clk, |
rxen => recv_rxen, |
recvo => recvo, |
inact => recv_inact, |
inbvalid => recv_inbvalid, |
inbits => recv_inbits ); |
|
-- Instantiate transmitter. |
xmit_sel0: if tximpl = impl_generic generate |
xmit_inst: spwxmit |
port map ( |
clk => clk, |
rst => rst, |
divcnt => xmit_divcnt, |
xmiti => xmiti, |
xmito => xmito, |
spw_do => spw_do, |
spw_so => spw_so ); |
end generate; |
xmit_sel1: if tximpl = impl_fast generate |
xmit_fast_inst: spwxmit_fast |
port map ( |
clk => clk, |
txclk => txclk, |
rst => rst, |
divcnt => xmit_divcnt, |
xmiti => xmiti, |
xmito => xmito, |
spw_do => spw_do, |
spw_so => spw_so ); |
end generate; |
|
-- Instantiate receiver front-end. |
recvfront_sel0: if rximpl = impl_generic generate |
recvfront_generic_inst: spwrecvfront_generic |
port map ( |
clk => clk, |
rxen => recv_rxen, |
inact => recv_inact, |
inbvalid => recv_inbvalid, |
inbits => recv_inbits, |
spw_di => spw_di, |
spw_si => spw_si ); |
end generate; |
recvfront_sel1: if rximpl = impl_fast generate |
recvfront_fast_inst: spwrecvfront_fast |
generic map ( |
rxchunk => rxchunk ) |
port map ( |
clk => clk, |
rxclk => rxclk, |
rxen => recv_rxen, |
inact => recv_inact, |
inbvalid => recv_inbvalid, |
inbits => recv_inbits, |
spw_di => spw_di, |
spw_si => spw_si ); |
end generate; |
|
-- Instantiate RX memory. |
rxmem: spwram |
generic map ( |
abits => rxfifosize_bits, |
dbits => 9 ) |
port map ( |
rclk => clk, |
wclk => clk, |
ren => '1', |
raddr => s_rxfifo_raddr, |
rdata => s_rxfifo_rdata, |
wen => s_rxfifo_wen, |
waddr => s_rxfifo_waddr, |
wdata => s_rxfifo_wdata ); |
|
-- Instantiate TX memory. |
txmem: spwram |
generic map ( |
abits => txfifosize_bits, |
dbits => 9 ) |
port map ( |
rclk => clk, |
wclk => clk, |
ren => '1', |
raddr => s_txfifo_raddr, |
rdata => s_txfifo_rdata, |
wen => s_txfifo_wen, |
waddr => s_txfifo_waddr, |
wdata => s_txfifo_wdata ); |
|
-- Combinatorial process |
process (r, linko, s_rxfifo_rdata, s_txfifo_rdata, rst, autostart, linkstart, linkdis, txdivcnt, tick_in, ctrl_in, time_in, txwrite, txflag, txdata, rxread) is |
variable v: regs_type; |
variable v_tmprxroom: unsigned(rxfifosize_bits-1 downto 0); |
variable v_tmptxroom: unsigned(txfifosize_bits-1 downto 0); |
begin |
v := r; |
v_tmprxroom := to_unsigned(0, v_tmprxroom'length); |
v_tmptxroom := to_unsigned(0, v_tmptxroom'length); |
|
-- Keep track of whether we are sending and/or receiving a packet. |
if linko.rxchar = '1' then |
-- got character |
v.rxpacket := not linko.rxflag; |
end if; |
if linko.txack = '1' then |
-- send character |
v.txpacket := not s_txfifo_rdata(8); |
end if; |
if linko.running = '0' then |
-- not connected |
v.rxpacket := '0'; |
v.txpacket := '0'; |
end if; |
|
-- Clear the discard flags when the link is explicitly disabled. |
if linkdis = '1' then |
v.rxeep := '0'; |
v.txdiscard := '0'; |
end if; |
|
-- Update RX fifo pointers. |
if (rxread = '1') and (r.rxfifo_rvalid = '1') then |
-- read from fifo |
v.rxfifo_raddr := std_logic_vector(unsigned(r.rxfifo_raddr) + 1); |
end if; |
if r.rxfull = '0' then |
if (linko.rxchar = '1') or (r.rxeep = '1') then |
-- write to fifo (received char or pending EEP) |
v.rxfifo_waddr := std_logic_vector(unsigned(r.rxfifo_waddr) + 1); |
end if; |
v.rxeep := '0'; |
end if; |
|
-- Keep track of whether the RX fifo contains valid data. |
-- (use new value of rxfifo_raddr) |
v.rxfifo_rvalid := bool_to_logic(v.rxfifo_raddr /= r.rxfifo_waddr); |
|
-- Update room in RX fifo (use new value of rxfifo_waddr). |
v_tmprxroom := unsigned(r.rxfifo_raddr) - unsigned(v.rxfifo_waddr) - 1; |
v.rxfull := bool_to_logic(v_tmprxroom = 0); |
v.rxhalff := not v_tmprxroom(v_tmprxroom'high); |
if v_tmprxroom > 63 then |
v.rxroom := (others => '1'); |
else |
v.rxroom := std_logic_vector(v_tmprxroom(5 downto 0)); |
end if; |
|
-- Update TX fifo pointers. |
if (r.txfifo_rvalid = '1') and ((linko.txack = '1') or (r.txdiscard = '1')) then |
-- read from fifo |
v.txfifo_raddr := std_logic_vector(unsigned(r.txfifo_raddr) + 1); |
if s_txfifo_rdata(8) = '1' then |
v.txdiscard := '0'; -- got EOP/EEP, stop discarding data |
end if; |
end if; |
if (r.txfull = '0') and (txwrite = '1') then |
-- write to fifo |
v.txfifo_waddr := std_logic_vector(unsigned(r.txfifo_waddr) + 1); |
end if; |
|
-- Keep track of whether the TX fifo contains valid data. |
-- (use new value of txfifo_raddr) |
v.txfifo_rvalid := bool_to_logic(v.txfifo_raddr /= r.txfifo_waddr); |
|
-- Update room in TX fifo (use new value of both txfifo_waddr). |
v_tmptxroom := unsigned(r.txfifo_raddr) - unsigned(v.txfifo_waddr) - 1; |
v.txfull := bool_to_logic(v_tmptxroom = 0); |
v.txhalff := not v_tmptxroom(v_tmptxroom'high); |
|
-- If an error occurs, set a flag to discard the current packet. |
if (linko.errdisc or linko.errpar or |
linko.erresc or linko.errcred) = '1' then |
v.rxeep := v.rxeep or v.rxpacket; -- use new value of rxpacket |
v.txdiscard := v.txdiscard or r.txpacket; |
v.rxpacket := '0'; |
v.txpacket := '0'; |
end if; |
|
-- Drive control signals to RX fifo. |
s_rxfifo_raddr <= v.rxfifo_raddr; -- using new value of rxfifo_raddr |
s_rxfifo_wen <= (not r.rxfull) and (linko.rxchar or r.rxeep); |
s_rxfifo_waddr <= r.rxfifo_waddr; |
if r.rxeep = '1' then |
s_rxfifo_wdata <= "100000001"; |
else |
s_rxfifo_wdata <= linko.rxflag & linko.rxdata; |
end if; |
|
-- Drive control signals to TX fifo. |
s_txfifo_raddr <= v.txfifo_raddr; -- using new value of txfifo_raddr |
s_txfifo_wen <= (not r.txfull) and txwrite; |
s_txfifo_waddr <= r.txfifo_waddr; |
s_txfifo_wdata <= txflag & txdata; |
|
-- Drive inputs to spwlink. |
linki.autostart <= autostart; |
linki.linkstart <= linkstart; |
linki.linkdis <= linkdis; |
linki.rxroom <= r.rxroom; |
linki.tick_in <= tick_in; |
linki.ctrl_in <= ctrl_in; |
linki.time_in <= time_in; |
linki.txwrite <= r.txfifo_rvalid and not r.txdiscard; |
linki.txflag <= s_txfifo_rdata(8); |
linki.txdata <= s_txfifo_rdata(7 downto 0); |
|
-- Drive divcnt input to spwxmit. |
if linko.running = '1' then |
xmit_divcnt <= txdivcnt; |
else |
xmit_divcnt <= default_divcnt; |
end if; |
|
-- Drive outputs. |
txrdy <= not r.txfull; |
txhalff <= r.txhalff; |
tick_out <= linko.tick_out; |
ctrl_out <= linko.ctrl_out; |
time_out <= linko.time_out; |
rxvalid <= r.rxfifo_rvalid; |
rxhalff <= r.rxhalff; |
rxflag <= s_rxfifo_rdata(8); |
rxdata <= s_rxfifo_rdata(7 downto 0); |
started <= linko.started; |
connecting <= linko.connecting; |
running <= linko.running; |
errdisc <= linko.errdisc; |
errpar <= linko.errpar; |
erresc <= linko.erresc; |
errcred <= linko.errcred; |
|
-- Reset. |
if rst = '1' then |
v.rxpacket := '0'; |
v.rxeep := '0'; |
v.txpacket := '0'; |
v.txdiscard := '0'; |
v.rxfifo_raddr := (others => '0'); |
v.rxfifo_waddr := (others => '0'); |
v.txfifo_raddr := (others => '0'); |
v.txfifo_waddr := (others => '0'); |
v.rxfifo_rvalid := '0'; |
v.txfifo_rvalid := '0'; |
end if; |
|
-- Update registers. |
rin <= v; |
end process; |
|
-- Update registers. |
process (clk) is |
begin |
if rising_edge(clk) then |
r <= rin; |
end if; |
end process; |
|
end architecture spwstream_arch; |
/rtl/vhdl/spwlink.vhd
0,0 → 1,282
-- |
-- SpaceWire Exchange Level Controller. |
-- |
-- This entity implements exchange level aspects of the SpaceWire protocol. |
-- It handles connection setup, error detection and flow control. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.spwpkg.all; |
|
entity spwlink is |
|
generic ( |
-- Reset time expressed in system clock cycles. |
-- Should be 6.4 us (5.82 us .. 7.2 us) according to the standard. |
reset_time: integer |
); |
|
port ( |
-- System clock. |
clk: in std_logic; |
|
-- Synchronous reset (active-high). |
-- Disconnects, resets error conditions, puts the link state machine |
-- in state ErrorReset. |
rst: in std_logic; |
|
-- Link level inputs. |
linki: in spw_link_in_type; |
|
-- Link level outputs. |
linko: out spw_link_out_type; |
|
-- Receiver enable signal to spwrecv. |
rxen: out std_logic; |
|
-- Output signals from spwrecv. |
recvo: in spw_recv_out_type; |
|
-- Input signals for spwxmit. |
xmiti: out spw_xmit_in_type; |
|
-- Output signals from spwxmit. |
xmito: in spw_xmit_out_type |
); |
|
end entity spwlink; |
|
architecture spwlink_arch of spwlink is |
|
-- Convert boolean to std_logic. |
type bool_to_logic_type is array(boolean) of std_ulogic; |
constant bool_to_logic: bool_to_logic_type := (false => '0', true => '1'); |
|
-- State machine. |
type state_type is ( |
S_ErrorReset, S_ErrorWait, S_Ready, S_Started, S_Connecting, S_Run ); |
|
-- Registers |
type regs_type is record |
-- state machine |
state: state_type; |
-- credit accounting |
tx_credit: unsigned(5 downto 0); |
rx_credit: unsigned(5 downto 0); |
errcred: std_ulogic; |
-- reset timer |
timercnt: unsigned(10 downto 0); |
timerdone: std_ulogic; |
-- signal to transmitter |
xmit_fct_in: std_ulogic; |
end record; |
|
-- Initial state |
constant regs_reset: regs_type := ( |
state => S_ErrorReset, |
tx_credit => "000000", |
rx_credit => "000000", |
errcred => '0', |
timercnt => to_unsigned(reset_time, 11), |
timerdone => '0', |
xmit_fct_in => '0' ); |
|
signal r: regs_type := regs_reset; |
signal rin: regs_type; |
|
begin |
|
-- Combinatorial process |
process (r, rst, linki, recvo, xmito) is |
variable v: regs_type; |
variable v_timerrst: std_logic; |
begin |
v := r; |
v_timerrst := '0'; |
|
-- State machine. |
case r.state is |
|
when S_ErrorReset => |
-- Wait for timer. |
if r.timercnt = 0 then |
v.state := S_ErrorWait; |
v_timerrst := '1'; |
end if; |
v.errcred := '0'; |
v.xmit_fct_in := '0'; |
|
when S_ErrorWait => |
-- Wait for 2 timer periods. |
if ((recvo.errdisc or recvo.errpar or recvo.erresc) = '1') or |
((recvo.gotfct or recvo.tick_out or recvo.rxchar) = '1') then |
v.state := S_ErrorReset; -- error, go back to reset |
v_timerrst := '1'; |
elsif r.timercnt = 0 then |
if r.timerdone = '1' then |
v.state := S_Ready; |
v_timerrst := '1'; |
end if; |
end if; |
|
when S_Ready => |
-- Wait for link start. |
if ((recvo.errdisc or recvo.errpar or recvo.erresc) = '1') or |
((recvo.gotfct or recvo.tick_out or recvo.rxchar) = '1') then |
v.state := S_ErrorReset; -- error, go back to reset |
v_timerrst := '1'; |
elsif (linki.linkdis = '0') and (r.xmit_fct_in = '1') and |
((linki.linkstart or (linki.autostart and recvo.gotnull)) = '1') then |
v.state := S_Started; -- link enabled; start sending NULL |
v_timerrst := '1'; |
end if; |
|
when S_Started => |
-- Wait for NULL. |
if ((recvo.errdisc or recvo.errpar or recvo.erresc) = '1') or |
((recvo.gotfct or recvo.tick_out or recvo.rxchar) = '1') or |
((r.timercnt = 0) and r.timerdone = '1') then |
v.state := S_ErrorReset; -- error, go back to reset |
v_timerrst := '1'; |
elsif recvo.gotnull = '1' then |
v.state := S_Connecting; -- received null, continue |
v_timerrst := '1'; |
end if; |
|
when S_Connecting => |
-- Wait for FCT. |
if ((recvo.errdisc or recvo.errpar or recvo.erresc) = '1') or |
((recvo.tick_out or recvo.rxchar) = '1') or |
((r.timercnt = 0) and r.timerdone = '1') then |
v.state := S_ErrorReset; -- error, go back to reset |
v_timerrst := '1'; |
elsif recvo.gotfct = '1' then |
v.state := S_Run; -- got FCT, init completed |
end if; |
|
when S_Run => |
-- All is well. |
if ((recvo.errdisc or recvo.errpar or recvo.erresc) = '1') or |
(r.errcred = '1') or |
(linki.linkdis = '1') then |
v.state := S_ErrorReset; -- error, go back to reset |
v_timerrst := '1'; |
end if; |
|
when others => |
v.state := S_ErrorReset; -- recover from invalid state |
v_timerrst := '1'; |
|
end case; |
|
-- Update credit counters. |
if r.state = S_ErrorReset then |
|
-- reset credit |
v.tx_credit := to_unsigned(0, v.tx_credit'length); |
v.rx_credit := to_unsigned(0, v.rx_credit'length); |
|
else |
|
-- update TX credit |
if recvo.gotfct = '1' then |
-- just received a FCT token |
v.tx_credit := v.tx_credit + to_unsigned(8, v.tx_credit'length); |
if r.tx_credit > 48 then |
-- received too many FCT tokens |
v.errcred := '1'; |
end if; |
end if; |
if xmito.txack = '1' then |
-- just sent one byte |
v.tx_credit := v.tx_credit - to_unsigned(1, v.tx_credit'length); |
end if; |
|
-- update RX credit after sending FCT |
if xmito.fctack = '1' then |
-- just sent a FCT token |
v.rx_credit := v.rx_credit + to_unsigned(8, v.rx_credit'length); |
end if; |
|
-- decide about sending FCT tokens |
v.xmit_fct_in := bool_to_logic( (v.rx_credit <= 48) and |
(v.rx_credit + to_unsigned(8, v.rx_credit'length) <= unsigned(linki.rxroom)) ); |
|
-- update RX credit after receiving character |
if recvo.rxchar = '1' then |
-- just received a character |
v.rx_credit := v.rx_credit - to_unsigned(1, v.rx_credit'length); |
if r.rx_credit = 0 then |
-- remote transmitter violated its credit |
v.errcred := '1'; |
end if; |
end if; |
|
end if; |
|
-- Update the initializaton reset timer. |
if v_timerrst = '1' then |
v.timercnt := to_unsigned(reset_time, v.timercnt'length); |
v.timerdone := '0'; |
else |
if r.timercnt = 0 then |
v.timercnt := to_unsigned(reset_time, v.timercnt'length); |
v.timerdone := '1'; |
else |
v.timercnt := r.timercnt - 1; |
end if; |
end if; |
|
-- Reset |
if rst = '1' then |
v := regs_reset; |
end if; |
|
-- Drive link level outputs. |
linko.started <= bool_to_logic(r.state = S_Started); |
linko.connecting <= bool_to_logic(r.state = S_Connecting); |
linko.running <= bool_to_logic(r.state = S_Run); |
linko.errdisc <= recvo.errdisc and bool_to_logic(r.state = S_Run); |
linko.errpar <= recvo.errpar and bool_to_logic(r.state = S_Run); |
linko.erresc <= recvo.erresc and bool_to_logic(r.state = S_Run); |
linko.errcred <= r.errcred; |
linko.txack <= xmito.txack; |
linko.tick_out <= recvo.tick_out and bool_to_logic(r.state = S_Run); |
linko.ctrl_out <= recvo.ctrl_out; |
linko.time_out <= recvo.time_out; |
linko.rxchar <= recvo.rxchar and bool_to_logic(r.state = S_Run); |
linko.rxflag <= recvo.rxflag; |
linko.rxdata <= recvo.rxdata; |
|
-- Drive receiver inputs. |
rxen <= bool_to_logic(r.state /= S_ErrorReset); |
|
-- Drive transmitter input signals. |
xmiti.txen <= bool_to_logic(r.state = S_Started or |
r.state = S_Connecting or |
r.state = S_Run); |
xmiti.stnull <= bool_to_logic(r.state = S_Started); |
xmiti.stfct <= bool_to_logic(r.state = S_Connecting); |
xmiti.fct_in <= r.xmit_fct_in; |
xmiti.tick_in <= linki.tick_in and bool_to_logic(r.state = S_Run); |
xmiti.ctrl_in <= linki.ctrl_in; |
xmiti.time_in <= linki.time_in; |
xmiti.txwrite <= linki.txwrite and bool_to_logic(r.tx_credit /= 0); |
xmiti.txflag <= linki.txflag; |
xmiti.txdata <= linki.txdata; |
|
-- Update registers. |
rin <= v; |
end process; |
|
-- Update registers. |
process (clk) is |
begin |
if rising_edge(clk) then |
r <= rin; |
end if; |
end process; |
|
end architecture spwlink_arch; |
/rtl/vhdl/spwxmit_fast.vhd
0,0 → 1,706
-- |
-- SpaceWire Transmitter |
-- |
-- This entity translates outgoing characters and tokens into |
-- data-strobe signalling. |
-- |
-- The output stage is driven by a separate transmission clock "txclk" which |
-- will typically be faster than the system clock. The actual transmission |
-- rate is determined by dividing the transmission clock by an integer factor. |
-- |
-- The code is tuned for implementation on Xilinx Spartan-3. |
-- |
-- Concept |
-- ------- |
-- |
-- Logic in the system clock domain generates a stream of tokens to be |
-- transmitted. These tokens are encoded as instances of the token_type |
-- record. Tokens are queued in a two-slot FIFO buffer (r.token0 and r.token1) |
-- with a 1-bit pointer (r.tokmux) pointing to the head of the queue. |
-- When a token is pushed into the buffer, a flag register is flipped |
-- (r.sysflip0 and r.sysflip1) to indicate to the txclk domain that the |
-- buffer slot has been refilled. |
-- |
-- The txclk domain pulls tokens from the FIFO buffer, flipping flag |
-- registers (rtx.txflip0 and rtx.txflip1) to indicate to the system clock |
-- domain that a token has been pulled. When the system clock domain detects |
-- that a token has been consumed, it refills the buffer slot with a new |
-- token (assuming that there are tokens waiting to be transmitted). |
-- Whenever the FIFO buffer is empty, the txclk domain sends NULLs instead. |
-- This can happen either when there are no tokens to send, or when the |
-- system clock domain is late to refill the buffer. |
-- |
-- Details |
-- ------- |
-- |
-- Logic in the system clock domain accepts transmission requests through |
-- the external interface of the entity. Pending requests are translated |
-- into a stream of tokens. The tokens are pushed to the txclk domain through |
-- the FIFO buffer as described above. |
-- |
-- The data path through the txclk domain is divided into stages A through F |
-- in a half-hearted attempt to keep things simple. Stage A is just a |
-- synchronizer for the buffer status flags from the system clock domain. |
-- |
-- Stage B takes a token from the FIFO buffer and updates a buffer status |
-- flag to indicate that the buffer slot needs to be refilled. If the FIFO |
-- is empty, a NULL is inserted. Stage B is triggered one clock after |
-- stage E switches to a new token. If the previous token was ESC, stage B |
-- skips a turn because stage C will already know what to do. |
-- |
-- Stage C takes a token from stage B and translates it into a bit pattern. |
-- Time codes and NULL tokens are broken into two separate tokens starting |
-- with ESC. Stage C is triggered one clock after the shift buffer in |
-- stage E drops to 3 tokens. |
-- |
-- Stage D completes the task of translating tokens to bit patterns and |
-- distinguishes between 10-bit and 4-bit tokens. It is not explicitly |
-- triggered but simply follows stage C. |
-- |
-- Stage E is the bit shift register. It shifts when "txclken" is high. |
-- A one-hot counter keeps track of the number of bits remaining in |
-- the register. When the register falls empty, it loads a new 10-bit or |
-- 4-bit pattern as prepared by stage D. Stage E also computes parity. |
-- |
-- Stage F performs data strobe encoding. When the transmitter is disabled, |
-- the outputs of stage F fall to zero in a controlled way. |
-- |
-- To generate the transmission bit clock, the txclk is divided by an |
-- integer factor (divcnt+1) using an 8-bit down counter. The implementation |
-- of this counter has become quite complicated in order to meet timing goals. |
-- The counter consists of 4 blocks of two bits each (txclkcnt), with a |
-- carry-save concept used between blocks (txclkcy). Detection of terminal |
-- count (txclkdone) has a pipeline delay of two cycles. Therefore a separate |
-- concept is used if the initial count is less than 2 (txdivnorm). This is |
-- all glued together in the final assignment to txclken. |
-- |
-- The initial count for txclk division (divcnt) comes from the system clock |
-- domain and thus needs to be synchronized for use in the txclk domain. |
-- To facilitate this, the system clock domain latches the value of divcnt |
-- once every 6 sysclk cycles and sets a flag to indicate when the latched |
-- value can safely be used by the txclk domain. |
-- |
-- A tricky aspect of the design is the initial state of the txclk logic. |
-- When the transmitter is enabled (txen goes high), the txclk logic starts |
-- with the first ESC pattern already set up in stage D, and stage C ready |
-- to produce the FCT part of the first NULL. |
-- |
-- The following guidelines are used to get good timing for the txclk domain: |
-- * The new value of a register depends on at most 4 inputs (single LUT), |
-- or in a few cases on 5 inputs (two LUTs and F5MUX). |
-- * Synchronous resets may be used, but only if the reset signal comes |
-- directly from a register (no logic in set/reset path); |
-- * Clock enables may be used, but only if the enable signal comes directly |
-- from a register (no logic in clock enable path). |
-- |
-- Synchronization issues |
-- ---------------------- |
-- |
-- There is a two-slot FIFO buffer between the system and txclk domains. |
-- After the txclk domain pulls a token from the buffer, the system clock |
-- domain should ideally refill the buffer before the txclk domain again |
-- tries to pull from the same buffer slot. If the refill occurs late, |
-- the txclk domain needs to insert a NULL token which is inefficient |
-- use of bandwidth. |
-- |
-- Assuming the transmission consists of a stream of data characters, |
-- 10 bits per character, there are exactly 2*10 bit periods between |
-- successive reads from the same buffer slot by the txclk logic. |
-- |
-- The time needed for the system clock logic to refill a buffer slot = |
-- 1 txclk period (update of rtx.txflipN) |
-- + 1 txclk period (routing delay between domains) |
-- + 2 sysclk periods (synchronizer for txflipN) |
-- + 1 sysclk period (refill buffer slot and update r.sysflipN) |
-- + 1 txclk period (routing delay between domains) |
-- + 2 txclk periods (synchronizer for sysflipN) |
-- = 5 txclk periods + 3 sysclk periods |
-- |
-- If for example txclk is 4 times as fast as sysclk, this amounts to |
-- 5 txclk + 3 sysclk = 5 + 3*4 txclk = 17 txclk |
-- is less than 20 bit periods even at maximum transmission rate, so |
-- no problem there. |
-- |
-- This is different when the data stream includes 4-bit tokens. |
-- See the datasheet for an analysis of that case. |
-- |
-- Implementation guidelines |
-- ------------------------- |
-- |
-- To minimize clock skew, IOB flip-flops should be used to drive |
-- spw_do and spw_so. |
-- |
-- "txclk" must be at least as fast as the system clock; |
-- "txclk" does not need to be phase-related to the system clock; |
-- it is allowed for "txclk" to be equal to "clk". |
-- |
-- The following timing constraints are needed: |
-- * PERIOD constraint on the system clock; |
-- * PERIOD constraint on "txclk"; |
-- * FROM-TO constraint from "txclk" to the system clock, equal to |
-- one "txclk" period; |
-- * FROM-TO constraint from the system clock to "txclk", equal to |
-- one "txclk" period. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.spwpkg.all; |
|
entity spwxmit_fast is |
|
port ( |
-- System clock. |
clk: in std_logic; |
|
-- Transmit clock. |
txclk: in std_logic; |
|
-- Synchronous reset (active-high) |
-- Used asynchronously by fast clock domain (must be glitch-free). |
rst: in std_logic; |
|
-- Scaling factor minus 1, used to scale the system clock into the |
-- transmission bit rate. The system clock is divided by |
-- (unsigned(divcnt) + 1). Changing this signal will immediately |
-- change the transmission rate. |
divcnt: in std_logic_vector(7 downto 0); |
|
-- Input signals from spwlink. |
xmiti: in spw_xmit_in_type; |
|
-- Output signals to spwlink. |
xmito: out spw_xmit_out_type; |
|
-- Data Out signal to SpaceWire bus. |
spw_do: out std_logic; |
|
-- Strobe Out signal to SpaceWire bus. |
spw_so: out std_logic |
); |
|
-- Turn off FSM extraction to avoid synchronization problems. |
attribute FSM_EXTRACT: string; |
attribute FSM_EXTRACT of spwxmit_fast: entity is "NO"; |
|
-- Turn off register duplication to avoid synchronization problems. |
attribute REGISTER_DUPLICATION: string; |
attribute REGISTER_DUPLICATION of spwxmit_fast: entity is "FALSE"; |
|
end entity spwxmit_fast; |
|
architecture spwxmit_fast_arch of spwxmit_fast is |
|
-- Convert boolean to std_logic. |
type bool_to_logic_type is array(boolean) of std_ulogic; |
constant bool_to_logic: bool_to_logic_type := (false => '0', true => '1'); |
|
-- Data records passed between clock domains. |
type token_type is record |
tick: std_ulogic; -- send time code |
fct: std_ulogic; -- send FCT |
flag: std_ulogic; -- send EOP or EEP |
char: std_logic_vector(7 downto 0); -- character or time code |
end record; |
|
-- Registers in txclk domain |
type txregs_type is record |
-- sync to system clock domain |
txflip0: std_ulogic; |
txflip1: std_ulogic; |
-- stage A |
a_sysflip0: std_logic_vector(1 downto 0); |
a_sysflip1: std_logic_vector(1 downto 0); |
-- stage B |
b_update: std_ulogic; |
b_mux: std_ulogic; |
b_txflip: std_ulogic; |
b_valid: std_ulogic; |
b_token: token_type; |
-- stage C |
c_update: std_ulogic; |
c_esc: std_ulogic; |
c_fct: std_ulogic; |
c_bits: std_logic_vector(8 downto 0); |
-- stage D |
d_bits: std_logic_vector(8 downto 0); |
d_cnt4: std_ulogic; |
d_cnt10: std_ulogic; |
-- stage E |
e_valid: std_ulogic; |
e_shift: std_logic_vector(9 downto 0); |
e_count: std_logic_vector(9 downto 0); |
e_parity: std_ulogic; |
-- stage F |
f_spwdo: std_ulogic; |
f_spwso: std_ulogic; |
-- tx clock enable logic |
txclken: std_ulogic; |
txclkpre: std_ulogic; |
txclkcnt: std_logic_vector(7 downto 0); |
txclkcy: std_logic_vector(2 downto 0); |
txclkdone: std_logic_vector(1 downto 0); |
txclkdiv: std_logic_vector(7 downto 0); |
txdivnorm: std_ulogic; |
txdivsafe: std_logic_vector(1 downto 0); |
-- tx enable logic |
txensync: std_logic_vector(1 downto 0); |
end record; |
|
-- Registers in system clock domain |
type regs_type is record |
-- sync status to txclk domain |
txenreg: std_ulogic; |
txdivreg: std_logic_vector(7 downto 0); |
txdivnorm: std_ulogic; |
txdivtmp: std_logic_vector(1 downto 0); |
txdivsafe: std_ulogic; |
-- data stream to txclk domain |
sysflip0: std_ulogic; |
sysflip1: std_ulogic; |
token0: token_type; |
token1: token_type; |
tokmux: std_ulogic; |
-- sync feedback from txclk domain |
txflip0: std_logic_vector(1 downto 0); |
txflip1: std_logic_vector(1 downto 0); |
-- transmitter management |
pend_fct: std_ulogic; -- '1' if an outgoing FCT is pending |
pend_char: std_ulogic; -- '1' if an outgoing N-Char is pending |
pend_data: std_logic_vector(8 downto 0); -- control flag and data bits of pending char |
pend_tick: std_ulogic; -- '1' if an outgoing time tick is pending |
pend_time: std_logic_vector(7 downto 0); -- data bits of pending time tick |
allow_fct: std_ulogic; -- '1' when allowed to send FCTs |
allow_char: std_ulogic; -- '1' when allowed to send data and time |
sent_fct: std_ulogic; -- '1' when at least one FCT token was sent |
end record; |
|
-- Initial state of system clock domain |
constant regs_reset: regs_type := ( |
txenreg => '0', |
txdivreg => (others => '0'), |
txdivnorm => '0', |
txdivtmp => "00", |
txdivsafe => '0', |
sysflip0 => '0', |
sysflip1 => '0', |
token0 => ( tick => '0', fct => '0', flag => '0', char => (others => '0') ), |
token1 => ( tick => '0', fct => '0', flag => '0', char => (others => '0') ), |
tokmux => '0', |
txflip0 => "00", |
txflip1 => "00", |
pend_fct => '0', |
pend_char => '0', |
pend_data => (others => '0'), |
pend_tick => '0', |
pend_time => (others => '0'), |
allow_fct => '0', |
allow_char => '0', |
sent_fct => '0' ); |
|
-- Registers |
signal rtx: txregs_type; |
signal rtxin: txregs_type; |
signal r: regs_type := regs_reset; |
signal rin: regs_type; |
|
-- Reset synchronizer for txclk domain |
signal s_tx_rst_sync: std_logic_vector(1 downto 0) := "11"; |
signal s_tx_reset: std_ulogic := '1'; |
|
-- Output flip-flops |
signal s_spwdo: std_logic; |
signal s_spwso: std_logic; |
|
-- Force use of IOB flip-flops |
attribute IOB: string; |
attribute IOB of s_spwdo: signal is "TRUE"; |
attribute IOB of s_spwso: signal is "TRUE"; |
|
begin |
|
-- Drive SpaceWire output signals |
spw_do <= s_spwdo; |
spw_so <= s_spwso; |
|
-- Combinatorial process |
process (r, rtx, rst, divcnt, xmiti, s_tx_reset) is |
variable v: regs_type; |
variable vtx: txregs_type; |
variable v_needtoken: std_ulogic; |
variable v_havetoken: std_ulogic; |
variable v_token: token_type; |
begin |
v := r; |
vtx := rtx; |
v_needtoken := '0'; |
v_havetoken := '0'; |
v_token := ( tick => '0', fct => '0', flag => '0', char => (others => '0') ); |
|
-- ---- FAST CLOCK DOMAIN ---- |
|
-- Stage A: Synchronize token buffer counts from system clock domain. |
vtx.a_sysflip0(0) := r.sysflip0; |
vtx.a_sysflip0(1) := rtx.a_sysflip0(0); |
vtx.a_sysflip1(0) := r.sysflip1; |
vtx.a_sysflip1(1) := rtx.a_sysflip1(0); |
|
-- Stage B: Multiplex tokens from system clock domain. |
-- Update stage B three bit periods after updating stage C |
-- (i.e. in time for the next update of stage C). |
-- Do not update stage B if the last token from stage C was ESC; |
-- stage C already knows what token to put after the ESC. |
vtx.b_update := rtx.txclken and rtx.e_count(0) and (not rtx.c_esc); |
if rtx.b_mux = '0' then |
vtx.b_txflip := rtx.txflip0; |
else |
vtx.b_txflip := rtx.txflip1; |
end if; |
if rtx.b_update = '1' then |
if rtx.b_mux = '0' then |
-- get token from slot 0 |
vtx.b_valid := rtx.a_sysflip0(1) xor rtx.b_txflip; |
vtx.b_token := r.token0; |
-- update mux flag if we got a valid token |
vtx.b_mux := rtx.a_sysflip0(1) xor rtx.b_txflip; |
vtx.txflip0 := rtx.a_sysflip0(1); |
vtx.txflip1 := rtx.txflip1; |
else |
-- get token from slot 1 |
vtx.b_valid := rtx.a_sysflip1(1) xor rtx.b_txflip; |
vtx.b_token := r.token1; |
-- update mux flag if we got a valid token |
vtx.b_mux := not (rtx.a_sysflip1(1) xor rtx.b_txflip); |
vtx.txflip0 := rtx.txflip0; |
vtx.txflip1 := rtx.a_sysflip1(1); |
end if; |
end if; |
|
-- Stage C: Prepare to transmit EOP, EEP or a data character. |
vtx.c_update := rtx.txclken and rtx.e_count(3); |
if rtx.c_update = '1' then |
-- NULL is broken into two tokens: ESC + FCT |
-- time codes are broken into two tokens: ESC + char |
vtx.c_esc := (rtx.b_token.tick or (not rtx.b_valid)) and |
(not rtx.c_esc); |
vtx.c_fct := rtx.b_token.fct or (not rtx.b_valid); |
if rtx.b_token.flag = '1' then |
if rtx.b_token.char(0) = '0' then |
-- prepare to send EOP |
vtx.c_bits := "000000101"; -- EOP = P101 |
else |
-- prepare to send EEP |
vtx.c_bits := "000000011"; -- EEP = P110 |
end if; |
else |
-- prepare to send data char |
vtx.c_bits := rtx.b_token.char & '0'; |
end if; |
end if; |
|
-- Stage D: Prepare to transmit FCT, ESC, or the stuff from stage C. |
if rtx.c_esc = '1' then |
-- prepare to send ESC |
vtx.d_bits := "000000111"; -- ESC = P111 |
vtx.d_cnt4 := '1'; -- 3 bits + implicit parity bit |
vtx.d_cnt10 := '0'; |
elsif rtx.c_fct = '1' then |
-- prepare to send FCT |
vtx.d_bits := "000000001"; -- FCT = P100 |
vtx.d_cnt4 := '1'; -- 3 bits + implicit parity bit |
vtx.d_cnt10 := '0'; |
else |
-- send the stuff from stage C. |
vtx.d_bits := rtx.c_bits; |
vtx.d_cnt4 := rtx.c_bits(0); |
vtx.d_cnt10 := not rtx.c_bits(0); |
end if; |
|
-- Stage E: Shift register. |
if rtx.txclken = '1' then |
if rtx.e_count(0) = '1' then |
-- reload shift register; output parity bit |
vtx.e_valid := '1'; |
vtx.e_shift(vtx.e_shift'high downto 1) := rtx.d_bits; |
vtx.e_shift(0) := not (rtx.e_parity xor rtx.d_bits(0)); |
vtx.e_count := rtx.d_cnt10 & "00000" & rtx.d_cnt4 & "000"; |
vtx.e_parity := rtx.d_bits(0); |
else |
-- shift bits to output; update parity bit |
vtx.e_shift := '0' & rtx.e_shift(rtx.e_shift'high downto 1); |
vtx.e_count := '0' & rtx.e_count(rtx.e_count'high downto 1); |
vtx.e_parity := rtx.e_parity xor rtx.e_shift(1); |
end if; |
end if; |
|
-- Stage F: Data/strobe encoding. |
if rtx.txclken = '1' then |
if rtx.e_valid = '1' then |
-- output next data/strobe bits |
vtx.f_spwdo := rtx.e_shift(0); |
vtx.f_spwso := not (rtx.e_shift(0) xor rtx.f_spwdo xor rtx.f_spwso); |
else |
-- gentle reset of spacewire signals |
vtx.f_spwdo := rtx.f_spwdo and rtx.f_spwso; |
vtx.f_spwso := '0'; |
end if; |
end if; |
|
-- Generate tx clock enable |
-- An 8-bit counter decrements on every clock. A txclken pulse is |
-- produced 2 cycles after the counter reaches value 2. Counter reload |
-- values of 0 and 1 are handled as special cases. |
-- count down in blocks of two bits |
vtx.txclkcnt(1 downto 0) := std_logic_vector(unsigned(rtx.txclkcnt(1 downto 0)) - 1); |
vtx.txclkcnt(3 downto 2) := std_logic_vector(unsigned(rtx.txclkcnt(3 downto 2)) - unsigned(rtx.txclkcy(0 downto 0))); |
vtx.txclkcnt(5 downto 4) := std_logic_vector(unsigned(rtx.txclkcnt(5 downto 4)) - unsigned(rtx.txclkcy(1 downto 1))); |
vtx.txclkcnt(7 downto 6) := std_logic_vector(unsigned(rtx.txclkcnt(7 downto 6)) - unsigned(rtx.txclkcy(2 downto 2))); |
-- propagate carry in blocks of two bits |
vtx.txclkcy(0) := bool_to_logic(rtx.txclkcnt(1 downto 0) = "00"); |
vtx.txclkcy(1) := rtx.txclkcy(0) and bool_to_logic(rtx.txclkcnt(3 downto 2) = "00"); |
vtx.txclkcy(2) := rtx.txclkcy(1) and bool_to_logic(rtx.txclkcnt(5 downto 4) = "00"); |
-- detect value 2 in counter |
vtx.txclkdone(0) := bool_to_logic(rtx.txclkcnt(3 downto 0) = "0010"); |
vtx.txclkdone(1) := bool_to_logic(rtx.txclkcnt(7 downto 4) = "0000"); |
-- trigger txclken |
vtx.txclken := (rtx.txclkdone(0) and rtx.txclkdone(1)) or rtx.txclkpre; |
vtx.txclkpre := (not rtx.txdivnorm) and ((not rtx.txclkpre) or (not rtx.txclkdiv(0))); |
-- reload counter |
if rtx.txclken = '1' then |
vtx.txclkcnt := rtx.txclkdiv; |
vtx.txclkcy := "000"; |
vtx.txclkdone := "00"; |
end if; |
|
-- Synchronize txclkdiv |
vtx.txdivsafe(0) := r.txdivsafe; |
vtx.txdivsafe(1) := rtx.txdivsafe(0); |
if rtx.txdivsafe(1) = '1' then |
vtx.txclkdiv := r.txdivreg; |
vtx.txdivnorm := r.txdivnorm; |
end if; |
|
-- Synchronize txen signal. |
vtx.txensync(0) := r.txenreg; |
vtx.txensync(1) := rtx.txensync(0); |
|
-- Transmitter disabled. |
if rtx.txensync(1) = '0' then |
vtx.txflip0 := '0'; |
vtx.txflip1 := '0'; |
vtx.b_update := '0'; |
vtx.b_mux := '0'; |
vtx.b_valid := '0'; |
vtx.c_update := '0'; |
vtx.c_esc := '1'; -- need to send 2nd part of NULL |
vtx.c_fct := '1'; |
vtx.d_bits := "000000111"; -- ESC = P111 |
vtx.d_cnt4 := '1'; -- 3 bits + implicit parity bit |
vtx.d_cnt10 := '0'; |
vtx.e_valid := '0'; |
vtx.e_parity := '0'; |
vtx.e_count := (0 => '1', others => '0'); |
end if; |
|
-- Reset. |
if s_tx_reset = '1' then |
vtx.f_spwdo := '0'; |
vtx.f_spwso := '0'; |
vtx.txensync := "00"; |
vtx.txclken := '0'; |
vtx.txclkpre := '1'; |
vtx.txclkcnt := (others => '0'); |
vtx.txclkdiv := (others => '0'); |
vtx.txdivnorm := '0'; |
end if; |
|
-- ---- SYSTEM CLOCK DOMAIN ---- |
|
-- Hold divcnt and txen for use by txclk domain. |
v.txdivtmp := std_logic_vector(unsigned(r.txdivtmp) - 1); |
if r.txdivtmp = "00" then |
if r.txdivsafe = '0' then |
-- Latch the current value of divcnt and txen. |
v.txdivsafe := '1'; |
v.txdivtmp := "01"; |
v.txdivreg := divcnt; |
if unsigned(divcnt(divcnt'high downto 1)) = 0 then |
v.txdivnorm := '0'; |
else |
v.txdivnorm := '1'; |
end if; |
v.txenreg := xmiti.txen; |
else |
-- Drop the txdivsafe flag but keep latched values. |
v.txdivsafe := '0'; |
end if; |
end if; |
|
-- Pass falling edge of txen signal as soon as possible. |
if xmiti.txen = '0' then |
v.txenreg := '0'; |
end if; |
|
-- Synchronize feedback from txclk domain. |
v.txflip0(0) := rtx.txflip0; |
v.txflip0(1) := r.txflip0(0); |
v.txflip1(0) := rtx.txflip1; |
v.txflip1(1) := r.txflip1(0); |
|
-- Store requests for FCT transmission. |
if xmiti.fct_in = '1' and r.allow_fct = '1' then |
v.pend_fct := '1'; |
end if; |
|
if xmiti.txen = '0' then |
|
-- Transmitter disabled; reset state. |
v.sysflip0 := '0'; |
v.sysflip1 := '0'; |
v.tokmux := '0'; |
v.pend_fct := '0'; |
v.pend_char := '0'; |
v.pend_tick := '0'; |
v.allow_fct := '0'; |
v.allow_char := '0'; |
v.sent_fct := '0'; |
|
else |
|
-- Determine if a new token is needed. |
if r.tokmux = '0' then |
if r.sysflip0 = r.txflip0(1) then |
v_needtoken := '1'; |
end if; |
else |
if r.sysflip1 = r.txflip1(1) then |
v_needtoken := '1'; |
end if; |
end if; |
|
-- Prepare new token. |
if r.allow_char = '1' and r.pend_tick = '1' then |
-- prepare to send time code |
v_token.tick := '1'; |
v_token.fct := '0'; |
v_token.flag := '0'; |
v_token.char := r.pend_time; |
v_havetoken := '1'; |
if v_needtoken = '1' then |
v.pend_tick := '0'; |
end if; |
elsif r.allow_fct = '1' and (xmiti.fct_in = '1' or r.pend_fct = '1') then |
-- prepare to send FCT |
v_token.tick := '0'; |
v_token.fct := '1'; |
v_token.flag := '0'; |
v_havetoken := '1'; |
if v_needtoken = '1' then |
v.pend_fct := '0'; |
v.sent_fct := '1'; |
end if; |
elsif r.allow_char = '1' and r.pend_char = '1' then |
-- prepare to send N-Char |
v_token.tick := '0'; |
v_token.fct := '0'; |
v_token.flag := r.pend_data(8); |
v_token.char := r.pend_data(7 downto 0); |
v_havetoken := '1'; |
if v_needtoken = '1' then |
v.pend_char := '0'; |
end if; |
end if; |
|
-- Put new token in slot. |
if v_havetoken = '1' then |
if r.tokmux = '0' then |
if r.sysflip0 = r.txflip0(1) then |
v.sysflip0 := not r.sysflip0; |
v.token0 := v_token; |
v.tokmux := '1'; |
end if; |
else |
if r.sysflip1 = r.txflip1(1) then |
v.sysflip1 := not r.sysflip1; |
v.token1 := v_token; |
v.tokmux := '0'; |
end if; |
end if; |
end if; |
|
-- Determine whether we are allowed to send FCTs and characters |
v.allow_fct := not xmiti.stnull; |
v.allow_char := (not xmiti.stnull) and (not xmiti.stfct) and r.sent_fct; |
|
-- Store request for data transmission. |
if xmiti.txwrite = '1' and r.allow_char = '1' and r.pend_char = '0' then |
v.pend_char := '1'; |
v.pend_data := xmiti.txflag & xmiti.txdata; |
end if; |
|
-- Store requests for time tick transmission. |
if xmiti.tick_in = '1' then |
v.pend_tick := '1'; |
v.pend_time := xmiti.ctrl_in & xmiti.time_in; |
end if; |
|
end if; |
|
-- Synchronous reset of system clock domain. |
if rst = '1' then |
v := regs_reset; |
end if; |
|
-- Drive outputs. |
-- Note: the outputs are combinatorially dependent on certain inputs. |
|
-- Set fctack high if (FCT requested) and (FCTs allowed) AND |
-- (no FCT pending) |
xmito.fctack <= xmiti.fct_in and xmiti.txen and r.allow_fct and |
(not r.pend_fct); |
|
-- Set txrdy high if (character requested) AND (characters allowed) AND |
-- (no character pending) |
xmito.txack <= xmiti.txwrite and xmiti.txen and r.allow_char and |
(not r.pend_char); |
|
-- Update registers. |
rin <= v; |
rtxin <= vtx; |
end process; |
|
-- Synchronous process in txclk domain |
process (txclk) is |
begin |
if rising_edge(txclk) then |
-- drive spacewire output signals |
s_spwdo <= rtx.f_spwdo; |
s_spwso <= rtx.f_spwso; |
-- update registers |
rtx <= rtxin; |
end if; |
end process; |
|
-- Synchronous process in system clock domain |
process (clk) is |
begin |
if rising_edge(clk) then |
-- update registers |
r <= rin; |
end if; |
end process; |
|
-- Reset synchronizer for txclk domain |
process (txclk, rst) is |
begin |
if rst = '1' then |
s_tx_rst_sync <= "11"; |
s_tx_reset <= '1'; |
elsif rising_edge(txclk) then |
s_tx_rst_sync <= s_tx_rst_sync(0 downto 0) & "0"; |
s_tx_reset <= s_tx_rst_sync(1); |
end if; |
end process; |
|
end architecture spwxmit_fast_arch; |
/rtl/vhdl/spwram.vhd
0,0 → 1,58
-- |
-- Synchronous dual-port RAM with separate clocks for read and write ports. |
-- The synthesizer for Xilinx Spartan-3 will infer Block RAM for this entity. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity spwram is |
|
generic ( |
abits: integer; |
dbits: integer ); |
|
port ( |
rclk: in std_logic; |
wclk: in std_logic; |
ren: in std_logic; |
raddr: in std_logic_vector(abits-1 downto 0); |
rdata: out std_logic_vector(dbits-1 downto 0); |
wen: in std_logic; |
waddr: in std_logic_vector(abits-1 downto 0); |
wdata: in std_logic_vector(dbits-1 downto 0) ); |
|
end entity spwram; |
|
architecture spwram_arch of spwram is |
|
type mem_type is array(0 to (2**abits - 1)) of |
std_logic_vector(dbits-1 downto 0); |
|
signal s_mem: mem_type; |
|
begin |
|
-- read process |
process (rclk) is |
begin |
if rising_edge(rclk) then |
if ren = '1' then |
rdata <= s_mem(to_integer(unsigned(raddr))); |
end if; |
end if; |
end process; |
|
-- write process |
process (wclk) is |
begin |
if rising_edge(wclk) then |
if wen = '1' then |
s_mem(to_integer(unsigned(waddr))) <= wdata; |
end if; |
end if; |
end process; |
|
end architecture; |
|
/rtl/vhdl/spwrecv.vhd
0,0 → 1,266
-- |
-- SpaceWire Receiver |
-- |
-- This entity decodes the sequence of incoming data bits into tokens. |
-- Data bits are passed to this entity from the Receiver Front-end |
-- in groups of rxchunk bits at a time. |
-- |
-- The bitrate of the incoming SpaceWire signal must be strictly less |
-- than rxchunk times the system clock frequency. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all, ieee.numeric_std.all; |
use work.spwpkg.all; |
|
entity spwrecv is |
|
generic ( |
-- Disconnect timeout, expressed in system clock cycles. |
-- Should be 850 ns (727 ns .. 1000 ns) according to the standard. |
disconnect_time: integer range 1 to 255; |
|
-- Nr of bits sampled per system clock. |
rxchunk: integer range 1 to 4 |
); |
|
port ( |
-- System clock. |
clk: in std_logic; |
|
-- High to enable receiver; low to disable and reset receiver. |
rxen: in std_logic; |
|
-- Output signals to spwlink. |
recvo: out spw_recv_out_type; |
|
-- High if there has been recent activity on the input lines. |
inact: in std_logic; |
|
-- High if inbits contains a valid group of received bits. |
inbvalid: in std_logic; |
|
-- Received bits from receiver front-end. |
inbits: in std_logic_vector(rxchunk-1 downto 0) |
); |
|
end entity spwrecv; |
|
architecture spwrecv_arch of spwrecv is |
|
-- registers |
type regs_type is record |
-- receiver state |
bit_seen: std_ulogic; -- got a bit transition |
null_seen: std_ulogic; -- got a NULL token |
-- input shift register |
bitshift: std_logic_vector(8 downto 0); |
bitcnt: std_logic_vector(9 downto 0); -- one-hot counter |
-- parity flag |
parity: std_ulogic; |
-- decoding |
control: std_ulogic; -- next code is control code |
escaped: std_ulogic; -- last code was ESC |
-- output registers |
gotfct: std_ulogic; |
tick_out: std_ulogic; |
rxchar: std_ulogic; |
rxflag: std_ulogic; |
timereg: std_logic_vector(7 downto 0); |
datareg: std_logic_vector(7 downto 0); |
-- disconnect timer |
disccnt: unsigned(7 downto 0); |
-- error flags |
errpar: std_ulogic; |
erresc: std_ulogic; |
end record; |
|
-- Initial state |
constant regs_reset: regs_type := ( |
bit_seen => '0', |
null_seen => '0', |
bitshift => (others => '1'), |
bitcnt => (others => '0'), |
parity => '0', |
control => '0', |
escaped => '0', |
gotfct => '0', |
tick_out => '0', |
rxchar => '0', |
rxflag => '0', |
timereg => (others => '0'), |
datareg => (others => '0'), |
disccnt => "00000000", |
errpar => '0', |
erresc => '0' ); |
|
-- registers |
signal r: regs_type := regs_reset; |
signal rin: regs_type; |
|
begin |
|
-- combinatorial process |
process (r, rxen, inact, inbvalid, inbits) |
variable v: regs_type; |
variable v_inbit: std_ulogic; |
begin |
v := r; |
v_inbit := '0'; |
|
-- disconnect timer |
if inact = '1' then |
-- activity on input; reset timer |
v.disccnt := to_unsigned(disconnect_time, v.disccnt'length); |
elsif r.disccnt /= 0 then |
-- count down |
v.disccnt := r.disccnt - 1; |
end if; |
|
-- assume no new token |
v.gotfct := '0'; |
v.tick_out := '0'; |
v.rxchar := '0'; |
|
if inbvalid = '1' then |
|
-- process incoming bits |
for i in 0 to rxchunk-1 loop |
v_inbit := inbits(i); |
|
-- got a bit transition |
v.bit_seen := '1'; |
|
if v.bitcnt(0) = '1' then |
-- received new token |
if (v.parity xor v_inbit) = '0' then |
-- Parity check failed. |
v.errpar := '1'; |
else |
if v.control = '1' then |
-- received control code |
case v.bitshift(7 downto 6) is |
when "00" => -- FCT or NULL |
v.gotfct := not r.escaped; |
v.escaped := '0'; |
when "10" => -- EOP |
if r.escaped = '1' then |
v.erresc := '1'; |
end if; |
v.escaped := '0'; |
v.rxchar := not r.escaped; |
v.rxflag := '1'; |
v.datareg := "00000000"; |
when "01" => -- EEP |
if r.escaped = '1' then |
v.erresc := '1'; |
end if; |
v.escaped := '0'; |
v.rxchar := not r.escaped; |
v.rxflag := '1'; |
v.datareg := "00000001"; |
when others => -- ESC |
if r.escaped = '1' then |
v.erresc := '1'; |
end if; |
v.escaped := '1'; |
end case; |
else |
-- received 8-bit character |
if r.escaped = '1' then |
-- received Time-Code |
v.tick_out := '1'; |
v.timereg := v.bitshift(7 downto 0); |
else |
-- received data character |
v.rxflag := '0'; |
v.rxchar := '1'; |
v.datareg := v.bitshift(7 downto 0); |
end if; |
v.escaped := '0'; |
end if; |
end if; |
-- prepare for next code |
v.parity := '0'; |
v.control := v_inbit; |
if v_inbit = '1' then |
-- next word will be control code. |
v.bitcnt := (3 => '1', others => '0'); |
else |
-- next word will be a data byte. |
v.bitcnt := (9 => '1', others => '0'); |
end if; |
else |
-- wait until next code is completely received; |
-- accumulate parity |
v.bitcnt := '0' & v.bitcnt(9 downto 1); |
v.parity := v.parity xor v_inbit; |
end if; |
|
-- detect first NULL |
if v.null_seen = '0' then |
if v.bitshift = "000101110" then |
-- got first NULL pattern |
v.null_seen := '1'; |
v.control := v_inbit; -- should always be '1' |
v.parity := '0'; |
v.bitcnt := (3 => '1', others => '0'); |
end if; |
end if; |
|
-- shift new bit into register. |
v.bitshift := v_inbit & v.bitshift(v.bitshift'high downto 1); |
|
end loop; |
end if; |
|
-- synchronous reset |
if rxen = '0' then |
v.bit_seen := '0'; |
v.null_seen := '0'; |
v.bitshift := "111111111"; |
v.bitcnt := (others => '0'); |
v.gotfct := '0'; |
v.tick_out := '0'; |
v.rxchar := '0'; |
v.rxflag := '0'; |
v.escaped := '0'; |
v.timereg := "00000000"; |
v.datareg := "00000000"; |
v.disccnt := to_unsigned(0, v.disccnt'length); |
v.errpar := '0'; |
v.erresc := '0'; |
end if; |
|
-- drive outputs |
recvo.gotbit <= r.bit_seen; |
recvo.gotnull <= r.null_seen; |
recvo.gotfct <= r.gotfct; |
recvo.tick_out <= r.tick_out; |
recvo.ctrl_out <= r.timereg(7 downto 6); |
recvo.time_out <= r.timereg(5 downto 0); |
recvo.rxchar <= r.rxchar; |
recvo.rxflag <= r.rxflag; |
recvo.rxdata <= r.datareg; |
if r.bit_seen = '1' and r.disccnt = 0 then |
recvo.errdisc <= '1'; |
else |
recvo.errdisc <= '0'; |
end if; |
recvo.errpar <= r.errpar; |
recvo.erresc <= r.erresc; |
|
-- update registers |
rin <= v; |
|
end process; |
|
-- update registers on rising edge of system clock |
process (clk) is |
begin |
if rising_edge(clk) then |
r <= rin; |
end if; |
end process; |
|
end architecture spwrecv_arch; |
/rtl/vhdl/spwxmit.vhd
0,0 → 1,249
-- |
-- SpaceWire Transmitter |
-- |
-- This entity translates outgoing characters and tokens into |
-- data-strobe signalling. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.spwpkg.all; |
|
entity spwxmit is |
|
port ( |
-- System clock. |
clk: in std_logic; |
|
-- Synchronous reset (active-high). |
rst: in std_logic; |
|
-- Scaling factor minus 1, used to scale the system clock into the |
-- transmission bit rate. The system clock is divided by |
-- (unsigned(divcnt) + 1). Changing this signal will immediately |
-- change the transmission rate. |
divcnt: in std_logic_vector(7 downto 0); |
|
-- Input signals from spwlink. |
xmiti: in spw_xmit_in_type; |
|
-- Output signals to spwlink. |
xmito: out spw_xmit_out_type; |
|
-- Data Out signal to SpaceWire bus. |
spw_do: out std_logic; |
|
-- Strobe Out signal to SpaceWire bus. |
spw_so: out std_logic |
); |
|
end entity spwxmit; |
|
architecture spwxmit_arch of spwxmit is |
|
-- Registers |
type regs_type is record |
-- tx clock |
txclken: std_ulogic; -- high if a bit must be transmitted |
txclkcnt: unsigned(7 downto 0); |
-- output shift register |
bitshift: std_logic_vector(12 downto 0); |
bitcnt: unsigned(3 downto 0); |
-- output signals |
out_data: std_ulogic; |
out_strobe: std_ulogic; |
-- parity flag |
parity: std_ulogic; |
-- pending time tick |
pend_tick: std_ulogic; |
pend_time: std_logic_vector(7 downto 0); |
-- transmitter mode |
allow_fct: std_ulogic; -- allowed to send FCTs |
allow_char: std_ulogic; -- allowed to send data and time |
sent_null: std_ulogic; -- sent at least one NULL token |
sent_fct: std_ulogic; -- sent at least one FCT token |
end record; |
|
-- Initial state |
constant regs_reset: regs_type := ( |
txclken => '0', |
txclkcnt => "00000000", |
bitshift => (others => '0'), |
bitcnt => "0000", |
out_data => '0', |
out_strobe => '0', |
parity => '0', |
pend_tick => '0', |
pend_time => (others => '0'), |
allow_fct => '0', |
allow_char => '0', |
sent_null => '0', |
sent_fct => '0' ); |
|
-- Registers |
signal r: regs_type := regs_reset; |
signal rin: regs_type; |
|
begin |
|
-- Combinatorial process |
process (r, rst, divcnt, xmiti) is |
variable v: regs_type; |
begin |
v := r; |
|
-- Generate TX clock. |
if r.txclkcnt = 0 then |
v.txclkcnt := unsigned(divcnt); |
v.txclken := '1'; |
else |
v.txclkcnt := r.txclkcnt - 1; |
v.txclken := '0'; |
end if; |
|
if xmiti.txen = '0' then |
|
-- Transmitter disabled; reset state. |
v.bitcnt := "0000"; |
v.parity := '0'; |
v.pend_tick := '0'; |
v.allow_fct := '0'; |
v.allow_char := '0'; |
v.sent_null := '0'; |
v.sent_fct := '0'; |
|
-- Gentle reset of spacewire bus signals |
if r.txclken = '1' then |
v.out_data := r.out_data and r.out_strobe; |
v.out_strobe := '0'; |
end if; |
|
else |
-- Transmitter enabled. |
|
v.allow_fct := (not xmiti.stnull) and r.sent_null; |
v.allow_char := (not xmiti.stnull) and r.sent_null and |
(not xmiti.stfct) and r.sent_fct; |
|
-- On tick of transmission clock, put next bit on the output. |
if r.txclken = '1' then |
|
if r.bitcnt = 0 then |
|
-- Need to start a new character. |
if (r.allow_char = '1') and (r.pend_tick = '1') then |
-- Send Time-Code. |
v.out_data := r.parity; |
v.bitshift(12 downto 5) := r.pend_time; |
v.bitshift(4 downto 0) := "01111"; |
v.bitcnt := to_unsigned(13, v.bitcnt'length); |
v.parity := '0'; |
v.pend_tick := '0'; |
elsif (r.allow_fct = '1') and (xmiti.fct_in = '1') then |
-- Send FCT. |
v.out_data := r.parity; |
v.bitshift(2 downto 0) := "001"; |
v.bitcnt := to_unsigned(3, v.bitcnt'length); |
v.parity := '1'; |
v.sent_fct := '1'; |
elsif (r.allow_char = '1') and (xmiti.txwrite = '1') then |
-- Send N-Char. |
v.bitshift(0) := xmiti.txflag; |
v.parity := xmiti.txflag; |
if xmiti.txflag = '0' then |
-- Data byte |
v.out_data := not r.parity; |
v.bitshift(8 downto 1) := xmiti.txdata; |
v.bitcnt := to_unsigned(9, v.bitcnt'length); |
else |
-- EOP or EEP |
v.out_data := r.parity; |
v.bitshift(1) := xmiti.txdata(0); |
v.bitshift(2) := not xmiti.txdata(0); |
v.bitcnt := to_unsigned(3, v.bitcnt'length); |
end if; |
else |
-- Send NULL. |
v.out_data := r.parity; |
v.bitshift(6 downto 0) := "0010111"; |
v.bitcnt := to_unsigned(7, v.bitcnt'length); |
v.parity := '0'; |
v.sent_null := '1'; |
end if; |
|
else |
|
-- Shift next bit to the output. |
v.out_data := r.bitshift(0); |
v.parity := r.parity xor r.bitshift(0); |
v.bitshift(r.bitshift'high-1 downto 0) := r.bitshift(r.bitshift'high downto 1); |
v.bitcnt := r.bitcnt - 1; |
|
end if; |
|
-- Data-Strobe encoding. |
v.out_strobe := not (r.out_strobe xor r.out_data xor v.out_data); |
|
end if; |
|
-- Store requests for time tick transmission. |
if xmiti.tick_in = '1' then |
v.pend_tick := '1'; |
v.pend_time := xmiti.ctrl_in & xmiti.time_in; |
end if; |
|
end if; |
|
-- Synchronous reset |
if rst = '1' then |
v := regs_reset; |
end if; |
|
-- Drive outputs. |
-- Note: the outputs are combinatorially dependent on certain inputs. |
|
-- Set fctack high if (transmitter enabled) AND |
-- (ready for token) AND (FCTs allowed) AND |
-- ((characters not allowed) OR (no timecode pending)) AND |
-- (FCT requested) |
if (xmiti.txen = '1') and |
(r.txclken = '1') and (r.bitcnt = 0) and (r.allow_fct = '1') and |
((r.allow_char = '0') or (r.pend_tick = '0')) then |
xmito.fctack <= xmiti.fct_in; |
else |
xmito.fctack <= '0'; |
end if; |
|
-- Set txrdy high if (transmitter enabled) AND |
-- (ready for token) AND (characters enabled) AND |
-- (no timecode pending) AND (no FCT requested) AND |
-- (character requested) |
if (xmiti.txen = '1') and |
(r.txclken = '1') and (r.bitcnt = 0) and (r.allow_char = '1') and |
(r.pend_tick = '0') and (xmiti.fct_in = '0') then |
xmito.txack <= xmiti.txwrite; |
else |
xmito.txack <= '0'; |
end if; |
|
-- Update registers |
rin <= v; |
end process; |
|
-- Synchronous process |
process (clk) is |
begin |
if rising_edge(clk) then |
|
-- Update registers |
r <= rin; |
|
-- Drive spacewire output signals |
spw_do <= r.out_data; |
spw_so <= r.out_strobe; |
|
end if; |
end process; |
|
end architecture spwxmit_arch; |
/rtl/vhdl/spwpkg.vhd
0,0 → 1,393
-- |
-- SpaceWire VHDL package |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
|
package spwpkg is |
|
|
-- Indicates a platform-specific implementation. |
type spw_implementation_type is ( impl_generic, impl_fast ); |
|
|
-- Input signals to spwlink. |
type spw_link_in_type is record |
|
-- Enables automatic link start on receipt of a NULL character. |
autostart: std_logic; |
|
-- Enables link start once the Ready state is reached. |
-- Without either "autostart" or "linkstart", the link remains in |
-- state Ready. |
linkstart: std_logic; |
|
-- Do not start link (overrides "linkstart" and "autostart") and/or |
-- disconnect the currently running link. |
linkdis: std_logic; |
|
-- Number of bytes available in the receive buffer. Used to for |
-- flow-control operation. At least 8 bytes must be available |
-- initially, otherwise the link can not start. Values larger than 63 |
-- are irrelevant and may be presented as 63. The available room may |
-- decrease by one byte due to the reception of an N-Char; in that case |
-- the "rxroom" signal must be updated on the clock following the clock |
-- on which "rxchar" is high. Under no other circumstances may "rxroom" |
-- be decreased. |
rxroom: std_logic_vector(5 downto 0); |
|
-- High for one clock cycle to request transmission of a TimeCode. |
-- The request is registered inside spwxmit until it can be processed. |
tick_in: std_logic; |
|
-- Control bits of the TimeCode to be sent. |
-- Must be valid while tick_in is high. |
ctrl_in: std_logic_vector(1 downto 0); |
|
-- Counter value of the TimeCode to be sent. |
-- Must be valid while tick_in is high. |
time_in: std_logic_vector(5 downto 0); |
|
-- Requests transmission of an N-Char. |
-- Keep this signal high until confirmed by "txack". |
txwrite: std_logic; |
|
-- Control flag to be sent with the next N-Char. |
-- Must be valid while "txwrite" is high. |
txflag: std_logic; |
|
-- Byte to be sent, or "00000000" for EOP or "00000001" for EEP. |
-- Must be valid while "txwrite" is high. |
txdata: std_logic_vector(7 downto 0); |
end record; |
|
|
-- Output signals from spwlink. |
type spw_link_out_type is record |
|
-- High if the link state machine is currently in state Started. |
started: std_logic; |
|
-- High if the link state machine is currently in state Connecting. |
connecting: std_logic; |
|
-- High if the link state machine is currently in state Run. |
running: std_logic; |
|
-- Disconnect detected in state Run. Triggers a reset and reconnect. |
-- This indication is auto-clearing. |
errdisc: std_logic; |
|
-- Parity error detected in state Run. Triggers a reset and reconnect. |
-- This indication is auto-clearing. |
errpar: std_logic; |
|
-- Invalid escape sequence detected in state Run. |
-- Triggers a reset and reconnect; auto-clearing. |
erresc: std_logic; |
|
-- Credit error detected. Triggers a reset and reconnect. |
-- This indication is auto-clearing. |
errcred: std_logic; |
|
-- High to confirm the transmission of an N-Char. |
-- This is a Wishbone-style handshake signal. It has a combinatorial |
-- dependency on "txwrite". |
txack: std_logic; |
|
-- High for one clock cycle if a TimeCode was just received. |
-- Verification of the TimeCode as described in 8.12.2 of ECSS-E-50 |
-- is not implemented; all received timecodes are reported. |
tick_out: std_logic; |
|
-- Control bits of last received TimeCode. |
ctrl_out: std_logic_vector(1 downto 0); |
|
-- Counter value of last received TimeCode. |
time_out: std_logic_vector(5 downto 0); |
|
-- High for one clock cycle if an N-Char (data byte or EOP or EEP) was |
-- just received. The data bits must be accepted immediately from |
-- "rxflag" and "rxdata". |
rxchar: std_logic; |
|
-- High if the received character is EOP or EEP, low if it is a data |
-- byte. Valid when "rxchar" is high. |
rxflag: std_logic; |
|
|
-- Received byte, or "00000000" for EOP or "00000001" for EEP. |
-- Valid when "rxchar" is high. |
rxdata: std_logic_vector(7 downto 0); |
end record; |
|
|
-- Output signals from spwrecv to spwlink. |
type spw_recv_out_type is record |
|
-- High if at least one signal change was seen since enable. |
-- Resets to low when rxen is low. |
gotbit: std_logic; |
|
-- High if at least one valid NULL pattern was detected since enable. |
-- Resets to low when rxen is low. |
gotnull: std_logic; |
|
-- High for one clock cycle if an FCT token was just received. |
gotfct: std_logic; |
|
-- High for one clock cycle if a TimeCode was just received. |
tick_out: std_logic; |
|
-- Control bits of last received TimeCode. |
ctrl_out: std_logic_vector(1 downto 0); |
|
-- Counter value of last received TimeCode. |
time_out: std_logic_vector(5 downto 0); |
|
-- High for one clock cycle if an N-Char (data byte or EOP/EEP) was just received. |
rxchar: std_logic; |
|
-- High if rxchar is high and the received character is EOP or EEP. |
-- Low if rxchar is high and the received character is a data byte. |
rxflag: std_logic; |
|
-- Received byte, or "00000000" for EOP or "00000001" for EEP. |
-- Valid when "rxchar" is high. |
rxdata: std_logic_vector(7 downto 0); |
|
-- Disconnect detected (after a signal change was seen). |
-- Resets to low when rxen is low or when a signal change is seen. |
errdisc: std_logic; |
|
-- Parity error detected (after a valid NULL pattern was seen). |
-- Sticky; resets to low when rxen is low. |
errpar: std_logic; |
|
-- Escape sequence error detected (after a valid NULL pattern was seen). |
-- Sticky; resets to low when rxen is low. |
erresc: std_logic; |
end record; |
|
|
-- Input signals to spwxmit from spwlink. |
type spw_xmit_in_type is record |
|
-- High to enable transmitter; low to disable and reset transmitter. |
txen: std_logic; |
|
-- Indicates that only NULL characters may be transmitted. |
stnull: std_logic; |
|
-- Indicates that only NULL and/or FCT characters may be transmitted. |
stfct: std_logic; |
|
-- Requests transmission of an FCT character. |
-- Keep this signal high until confirmed by "fctack". |
fct_in: std_logic; |
|
-- High for one clock cycle to request transmission of a TimeCode. |
-- The request is registered inside spwxmit until it can be processed. |
tick_in: std_logic; |
|
-- Control bits of the TimeCode to be sent. |
-- Must be valid while "tick_in" is high. |
ctrl_in: std_logic_vector(1 downto 0); |
|
-- Counter value of the TimeCode to be sent. |
-- Must be valid while "tick_in" is high. |
time_in: std_logic_vector(5 downto 0); |
|
-- Request transmission of an N-Char. |
-- Keep this signal high until confirmed by "txack". |
txwrite: std_logic; |
|
-- Control flag to be sent with the next N-Char. |
-- Must be valid while "txwrite" is high. |
txflag: std_logic; |
|
-- Byte to send, or "00000000" for EOP or "00000001" for EEP. |
-- Must be valid while "txwrite" is high. |
txdata: std_logic_vector(7 downto 0); |
end record; |
|
|
-- Output signals from spwxmit to spwlink. |
type spw_xmit_out_type is record |
|
-- High to confirm transmission on an FCT character. |
-- This is a Wishbone-style handshaking signal; it is combinatorially |
-- dependent on "fct_in". |
fctack: std_logic; |
|
-- High to confirm transmission of an N-Char. |
-- This is a Wishbone-style handshaking signal; it is combinatorially |
-- dependent on both "fct_in" and "txwrite". |
txack: std_logic; |
end record; |
|
|
-- Character-stream interface |
component spwstream is |
generic ( |
sysfreq: real; -- clk freq in Hz |
rximpl: spw_implementation_type := impl_generic; |
rxchunk: integer range 1 to 4 := 1; -- max bits per clk |
tximpl: spw_implementation_type := impl_generic; |
rxfifosize_bits: integer range 6 to 14 := 11; -- rx fifo size |
txfifosize_bits: integer range 2 to 14 := 11 -- tx fifo size |
); |
port ( |
clk: in std_logic; -- system clock |
rxclk: in std_logic; -- receiver sample clock |
txclk: in std_logic; -- transmit clock |
rst: in std_logic; -- synchronous reset |
autostart: in std_logic; -- automatic link start |
linkstart: in std_logic; -- forced link start |
linkdis: in std_logic; -- stop link |
txdivcnt: in std_logic_vector(7 downto 0); -- tx scale factor |
tick_in: in std_logic; -- request timecode xmit |
ctrl_in: in std_logic_vector(1 downto 0); |
time_in: in std_logic_vector(5 downto 0); |
txwrite: in std_logic; -- request character xmit |
txflag: in std_logic; -- control flag of tx char |
txdata: in std_logic_vector(7 downto 0); |
txrdy: out std_logic; -- room in tx fifo |
txhalff: out std_logic; -- tx fifo half full |
tick_out: out std_logic; -- timecode received |
ctrl_out: out std_logic_vector(1 downto 0); |
time_out: out std_logic_vector(5 downto 0); |
rxvalid: out std_logic; -- rx fifo not empty |
rxhalff: out std_logic; -- rx fifo half full |
rxflag: out std_logic; -- control flag of rx char |
rxdata: out std_logic_vector(7 downto 0); |
rxread: in std_logic; -- accept rx character |
started: out std_logic; -- link in Started state |
connecting: out std_logic; -- link in Connecting state |
running: out std_logic; -- link in Run state |
errdisc: out std_logic; -- disconnect error |
errpar: out std_logic; -- parity error |
erresc: out std_logic; -- escape error |
errcred: out std_logic; -- credit error |
spw_di: in std_logic; |
spw_si: in std_logic; |
spw_do: out std_logic; |
spw_so: out std_logic |
); |
end component spwstream; |
|
|
-- Link Level Interface |
component spwlink is |
generic ( |
reset_time: integer -- reset time in clocks (6.4 us) |
); |
port ( |
clk: in std_logic; -- system clock |
rst: in std_logic; -- synchronous reset (active-high) |
linki: in spw_link_in_type; |
linko: out spw_link_out_type; |
rxen: out std_logic; |
recvo: in spw_recv_out_type; |
xmiti: out spw_xmit_in_type; |
xmito: in spw_xmit_out_type |
); |
end component spwlink; |
|
|
-- Receiver |
component spwrecv is |
generic ( |
disconnect_time: integer range 1 to 255; -- disconnect period in system clock cycles |
rxchunk: integer range 1 to 4 -- nr of bits per system clock |
); |
port ( |
clk: in std_logic; -- system clock |
rxen: in std_logic; -- receiver enabled |
recvo: out spw_recv_out_type; |
inact: in std_logic; |
inbvalid: in std_logic; |
inbits: in std_logic_vector(rxchunk-1 downto 0) |
); |
end component spwrecv; |
|
|
-- Transmitter (generic implementation) |
component spwxmit is |
port ( |
clk: in std_logic; -- system clock |
rst: in std_logic; -- synchronous reset (active-high) |
divcnt: in std_logic_vector(7 downto 0); |
xmiti: in spw_xmit_in_type; |
xmito: out spw_xmit_out_type; |
spw_do: out std_logic; -- tx data to SPW bus |
spw_so: out std_logic -- tx strobe to SPW bus |
); |
end component spwxmit; |
|
|
-- Transmitter (separate tx clock domain) |
component spwxmit_fast is |
port ( |
clk: in std_logic; -- system clock |
txclk: in std_logic; -- transmit clock |
rst: in std_logic; -- synchronous reset (active-high) |
divcnt: in std_logic_vector(7 downto 0); |
xmiti: in spw_xmit_in_type; |
xmito: out spw_xmit_out_type; |
spw_do: out std_logic; -- tx data to SPW bus |
spw_so: out std_logic -- tx strobe to SPW bus |
); |
end component spwxmit_fast; |
|
|
-- Front-end for SpaceWire Receiver (generic implementation) |
component spwrecvfront_generic is |
port ( |
clk: in std_logic; -- system clock |
rxen: in std_logic; -- high to enable receiver |
inact: out std_logic; -- high if activity on input |
inbvalid: out std_logic; -- high if inbits contains a valid received bit |
inbits: out std_logic_vector(0 downto 0); -- received bit |
spw_di: in std_logic; -- Data In signal from SpaceWire bus |
spw_si: in std_logic -- Strobe In signal from SpaceWire bus |
); |
end component spwrecvfront_generic; |
|
|
-- Front-end for SpaceWire Receiver (separate rx clock domain) |
component spwrecvfront_fast is |
generic ( |
rxchunk: integer range 1 to 4 -- max number of bits per system clock |
); |
port ( |
clk: in std_logic; -- system clock |
rxclk: in std_logic; -- sample clock (DDR) |
rxen: in std_logic; -- high to enable receiver |
inact: out std_logic; -- high if activity on input |
inbvalid: out std_logic; -- high if inbits contains a valid group of received bits |
inbits: out std_logic_vector(rxchunk-1 downto 0); -- received bits |
spw_di: in std_logic; -- Data In signal from SpaceWire bus |
spw_si: in std_logic -- Strobe In signal from SpaceWire bus |
); |
end component spwrecvfront_fast; |
|
|
-- Synchronous dual-port memory. |
component spwram is |
generic ( |
abits: integer; |
dbits: integer ); |
port ( |
rclk: in std_logic; |
wclk: in std_logic; |
ren: in std_logic; |
raddr: in std_logic_vector(abits-1 downto 0); |
rdata: out std_logic_vector(dbits-1 downto 0); |
wen: in std_logic; |
waddr: in std_logic_vector(abits-1 downto 0); |
wdata: in std_logic_vector(dbits-1 downto 0) ); |
end component spwram; |
|
end package; |
/rtl/vhdl/streamtest.vhd
0,0 → 1,442
-- |
-- Test application for spwstream. |
-- |
-- This entity implements one spwstream instance with SpaceWire signals |
-- routed to external ports. The SpaceWire port is assumed to be looped back |
-- to itself externally, either directly (tx pins wired to rx pins) or |
-- through a foreigh SpaceWire device which is programmed to echo anything |
-- it receives. |
-- |
-- This entity submits a series of test patterns to the transmit side of |
-- spwstream. At the same time it monitors the receive side of spwstream |
-- and verifies that received data matches the transmitted data pattern. |
-- |
-- Link mode and tx bit rate may be programmed through digital inputs |
-- (presumably connected to switches or buttons). Link state and progress of |
-- the test are reported through digital outputs (presumably connected to |
-- LEDs). |
-- |
-- Note: there is no check on the integrity of the first packet received |
-- after the link goes up. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
use work.spwpkg.all; |
|
entity streamtest is |
|
generic ( |
-- System clock frequency in Hz. |
sysfreq: real; |
|
-- 2-log of division factor from system clock freq to timecode freq. |
tickdiv: integer range 12 to 24 := 20; |
|
-- Receiver front-end implementation. |
rximpl: spw_implementation_type := impl_generic; |
|
-- Maximum number of bits received per system clock (impl_fast only). |
rxchunk: integer range 1 to 4 := 1; |
|
-- Transmitter implementation. |
tximpl: spw_implementation_type := impl_generic; |
|
-- Size of receive FIFO. |
rxfifosize_bits: integer range 6 to 14 := 11; |
|
-- Size of transmit FIFO. |
txfifosize_bits: integer range 2 to 14 := 11 ); |
|
port ( |
-- System clock. |
clk: in std_logic; |
|
-- Receiver sample clock (only for impl_fast). |
rxclk: in std_logic; |
|
-- Transmit clock (only for impl_fast). |
txclk: in std_logic; |
|
-- Synchronous reset (active-high). |
rst: in std_logic; |
|
-- Enables spontaneous link start. |
linkstart: in std_logic; |
|
-- Enables automatic link start on receipt of a NULL token. |
autostart: in std_logic; |
|
-- Do not start link and/or disconnect current link. |
linkdisable: in std_logic; |
|
-- Enable sending test patterns to spwstream. |
senddata: in std_logic; |
|
-- Enable sending time codes to spwstream. |
sendtick: in std_logic; |
|
-- Scaling factor minus 1 for TX bitrate. |
txdivcnt: in std_logic_vector(7 downto 0); |
|
-- Link in state Started. |
linkstarted: out std_logic; |
|
-- Link in state Connecting. |
linkconnecting: out std_logic; |
|
-- Link in state Run. |
linkrun: out std_logic; |
|
-- Link error (one cycle pulse, not directly suitable for LED) |
linkerror: out std_logic; |
|
-- High when taking a byte from the receive FIFO. |
gotdata: out std_logic; |
|
-- Incorrect or unexpected data received (sticky). |
dataerror: out std_logic; |
|
-- Incorrect or unexpected time code received (sticky). |
tickerror: out std_logic; |
|
-- SpaceWire signals. |
spw_di: in std_logic; |
spw_si: in std_logic; |
spw_do: out std_logic; |
spw_so: out std_logic ); |
|
end entity streamtest; |
|
architecture streamtest_arch of streamtest is |
|
-- Update 16-bit maximum length LFSR by 8 steps |
function lfsr16(x: in std_logic_vector) return std_logic_vector is |
variable y: std_logic_vector(15 downto 0); |
begin |
-- poly = x^16 + x^14 + x^13 + x^11 + 1 |
-- tap positions = x(0), x(2), x(3), x(5) |
y(7 downto 0) := x(15 downto 8); |
y(15 downto 8) := x(7 downto 0) xor x(9 downto 2) xor x(10 downto 3) xor x(12 downto 5); |
return y; |
end function; |
|
-- Sending side state. |
type tx_state_type is ( txst_idle, txst_prepare, txst_data ); |
|
-- Receiving side state. |
type rx_state_type is ( rxst_idle, rxst_data ); |
|
-- Registers. |
type regs_type is record |
tx_state: tx_state_type; |
tx_timecnt: std_logic_vector((tickdiv-1) downto 0); |
tx_quietcnt: std_logic_vector(15 downto 0); |
tx_pktlen: std_logic_vector(15 downto 0); |
tx_lfsr: std_logic_vector(15 downto 0); |
tx_enabledata: std_ulogic; |
rx_state: rx_state_type; |
rx_quietcnt: std_logic_vector(15 downto 0); |
rx_enabledata: std_ulogic; |
rx_gottick: std_ulogic; |
rx_expecttick: std_ulogic; |
rx_expectglitch: unsigned(5 downto 0); |
rx_badpacket: std_ulogic; |
rx_pktlen: std_logic_vector(15 downto 0); |
rx_prev: std_logic_vector(15 downto 0); |
rx_lfsr: std_logic_vector(15 downto 0); |
running: std_ulogic; |
tick_in: std_ulogic; |
time_in: std_logic_vector(5 downto 0); |
txwrite: std_ulogic; |
txflag: std_ulogic; |
txdata: std_logic_vector(7 downto 0); |
rxread: std_ulogic; |
gotdata: std_ulogic; |
dataerror: std_ulogic; |
tickerror: std_ulogic; |
end record; |
|
-- Reset state. |
constant regs_reset: regs_type := ( |
tx_state => txst_idle, |
tx_timecnt => (others => '0'), |
tx_quietcnt => (others => '0'), |
tx_pktlen => (others => '0'), |
tx_lfsr => (1 => '1', others => '0'), |
tx_enabledata => '0', |
rx_state => rxst_idle, |
rx_quietcnt => (others => '0'), |
rx_enabledata => '0', |
rx_gottick => '0', |
rx_expecttick => '0', |
rx_expectglitch => "000001", |
rx_badpacket => '0', |
rx_pktlen => (others => '0'), |
rx_prev => (others => '0'), |
rx_lfsr => (others => '0'), |
running => '0', |
tick_in => '0', |
time_in => (others => '0'), |
txwrite => '0', |
txflag => '0', |
txdata => (others => '0'), |
rxread => '0', |
gotdata => '0', |
dataerror => '0', |
tickerror => '0' ); |
|
signal r: regs_type := regs_reset; |
signal rin: regs_type; |
|
-- Interface signals. |
signal s_txrdy: std_logic; |
signal s_tickout: std_logic; |
signal s_timeout: std_logic_vector(5 downto 0); |
signal s_rxvalid: std_logic; |
signal s_rxflag: std_logic; |
signal s_rxdata: std_logic_vector(7 downto 0); |
signal s_running: std_logic; |
signal s_errdisc: std_logic; |
signal s_errpar: std_logic; |
signal s_erresc: std_logic; |
signal s_errcred: std_logic; |
|
begin |
|
-- spwstream instance |
spwstream_inst: spwstream |
generic map ( |
sysfreq => sysfreq, |
rximpl => rximpl, |
rxchunk => rxchunk, |
tximpl => tximpl, |
rxfifosize_bits => rxfifosize_bits, |
txfifosize_bits => txfifosize_bits ) |
port map ( |
clk => clk, |
rxclk => rxclk, |
txclk => txclk, |
rst => rst, |
autostart => autostart, |
linkstart => linkstart, |
linkdis => linkdisable, |
txdivcnt => txdivcnt, |
tick_in => r.tick_in, |
ctrl_in => (others => '0'), |
time_in => r.time_in, |
txwrite => r.txwrite, |
txflag => r.txflag, |
txdata => r.txdata, |
txrdy => s_txrdy, |
txhalff => open, |
tick_out => s_tickout, |
ctrl_out => open, |
time_out => s_timeout, |
rxvalid => s_rxvalid, |
rxhalff => open, |
rxflag => s_rxflag, |
rxdata => s_rxdata, |
rxread => r.rxread, |
started => linkstarted, |
connecting => linkconnecting, |
running => s_running, |
errdisc => s_errdisc, |
errpar => s_errpar, |
erresc => s_erresc, |
errcred => s_errcred, |
spw_di => spw_di, |
spw_si => spw_si, |
spw_do => spw_do, |
spw_so => spw_so ); |
|
-- Drive status indications. |
linkrun <= s_running; |
linkerror <= s_errdisc or s_errpar or s_erresc or s_errcred; |
gotdata <= r.gotdata; |
dataerror <= r.dataerror; |
tickerror <= r.tickerror; |
|
process (r, rst, senddata, sendtick, s_txrdy, s_tickout, s_timeout, s_rxvalid, s_rxflag, s_rxdata, s_running) is |
variable v: regs_type; |
begin |
v := r; |
|
-- Initiate timecode transmissions. |
v.tx_timecnt := std_logic_vector(unsigned(r.tx_timecnt) + 1); |
if unsigned(v.tx_timecnt) = 0 then |
v.tick_in := sendtick; |
else |
v.tick_in := '0'; |
end if; |
if r.tick_in = '1' then |
v.time_in := std_logic_vector(unsigned(r.time_in) + 1); |
v.rx_expecttick := '1'; |
v.rx_gottick := '0'; |
end if; |
|
-- Turn data generator on/off at regular intervals. |
v.tx_quietcnt := std_logic_vector(unsigned(r.tx_quietcnt) + 1); |
if unsigned(r.tx_quietcnt) = 61000 then |
v.tx_quietcnt := (others => '0'); |
end if; |
v.tx_enabledata := senddata and (not r.tx_quietcnt(15)); |
|
-- Generate data packets. |
case r.tx_state is |
when txst_idle => |
-- generate packet length |
v.tx_state := txst_prepare; |
v.tx_pktlen := r.tx_lfsr; |
v.txwrite := '0'; |
v.tx_lfsr := lfsr16(r.tx_lfsr); |
when txst_prepare => |
-- generate first byte of packet |
v.tx_state := txst_data; |
v.txwrite := r.tx_enabledata; |
v.txflag := '0'; |
v.txdata := r.tx_lfsr(15 downto 8); |
v.tx_lfsr := lfsr16(r.tx_lfsr); |
when txst_data => |
-- generate data bytes and EOP |
v.txwrite := r.tx_enabledata; |
if r.txwrite = '1' and s_txrdy = '1' then |
-- just sent one byte |
v.tx_pktlen := std_logic_vector(unsigned(r.tx_pktlen) - 1); |
if unsigned(r.tx_pktlen) = 0 then |
-- done with packet |
v.tx_state := txst_idle; |
v.txwrite := '0'; |
elsif unsigned(r.tx_pktlen) = 1 then |
-- generate EOP |
v.txwrite := r.tx_enabledata; |
v.txflag := '1'; |
v.txdata := (others => '0'); |
v.tx_lfsr := lfsr16(r.tx_lfsr); |
else |
-- generate next data byte |
v.txwrite := r.tx_enabledata; |
v.txflag := '0'; |
v.txdata := r.tx_lfsr(15 downto 8); |
v.tx_lfsr := lfsr16(r.tx_lfsr); |
end if; |
end if; |
end case; |
|
-- Blink light when receiving data. |
v.gotdata := s_rxvalid and r.rxread; |
|
-- Detect missing timecodes. |
if r.tick_in = '1' and r.rx_expecttick = '1' then |
-- This is bad; a new timecode is being generated while |
-- we have not even received the previous one yet. |
v.tickerror := '1'; |
end if; |
|
-- Receive and check incoming timecodes. |
if s_tickout = '1' then |
if unsigned(s_timeout) + 1 /= unsigned(r.time_in) then |
-- Received time code does not match last transmitted code. |
v.tickerror := '1'; |
end if; |
if r.rx_gottick = '1' then |
-- Already received the last transmitted time code. |
v.tickerror := '1'; |
end if; |
v.rx_expecttick := '0'; |
v.rx_gottick := '1'; |
end if; |
|
-- Turn data receiving on/off at regular intervals |
v.rx_quietcnt := std_logic_vector(unsigned(r.rx_quietcnt) + 1); |
if unsigned(r.rx_quietcnt) = 55000 then |
v.rx_quietcnt := (others => '0'); |
end if; |
v.rx_enabledata := not r.rx_quietcnt(15); |
|
case r.rx_state is |
when rxst_idle => |
-- get expected packet length |
v.rx_state := rxst_data; |
v.rx_pktlen := r.rx_lfsr; |
v.rx_lfsr := lfsr16(r.rx_lfsr); |
v.rx_prev := (others => '0'); |
when rxst_data => |
v.rxread := r.rx_enabledata; |
if r.rxread = '1' and s_rxvalid = '1' then |
-- got next byte |
v.rx_pktlen := std_logic_vector(unsigned(r.rx_pktlen) - 1); |
v.rx_prev := s_rxdata & r.rx_prev(15 downto 8); |
if s_rxflag = '1' then |
-- got EOP or EEP |
v.rxread := '0'; |
v.rx_state := rxst_idle; |
if s_rxdata = "00000000" then |
-- got EOP |
if unsigned(r.rx_pktlen) /= 0 then |
-- unexpected EOP |
v.rx_badpacket := '1'; |
end if; |
-- count errors against expected glitches |
if v.rx_badpacket = '1' then |
-- got glitch |
if r.rx_expectglitch = 0 then |
v.dataerror := '1'; |
else |
v.rx_expectglitch := r.rx_expectglitch - 1; |
end if; |
end if; |
-- resynchronize LFSR |
v.rx_lfsr := lfsr16(lfsr16(r.rx_prev)); |
else |
-- got EEP |
v.rx_badpacket := '1'; |
end if; |
v.rx_badpacket := '0'; |
else |
-- got next byte |
v.rx_lfsr := lfsr16(r.rx_lfsr); |
if unsigned(r.rx_pktlen) = 0 then |
-- missing EOP |
v.rx_badpacket := '1'; |
end if; |
if s_rxdata /= r.rx_lfsr(15 downto 8) then |
-- bad data |
v.rx_badpacket := '1'; |
end if; |
end if; |
end if; |
end case; |
|
-- If the link goes away, we should expect inconsistency on the receiving side. |
v.running := s_running; |
if r.running = '1' and s_running = '0' then |
if r.rx_expectglitch /= "111111" then |
v.rx_expectglitch := r.rx_expectglitch + 1; |
end if; |
end if; |
|
-- If there is no link, we should not expect to receive time codes. |
if s_running = '0' then |
v.rx_expecttick := '0'; |
end if; |
|
-- Synchronous reset. |
if rst = '1' then |
v := regs_reset; |
end if; |
|
-- Update registers. |
rin <= v; |
end process; |
|
-- Update registers. |
process (clk) is |
begin |
if rising_edge(clk) then |
r <= rin; |
end if; |
end process; |
|
end architecture streamtest_arch; |
/rtl/vhdl/spwrecvfront_generic.vhd
0,0 → 1,95
-- |
-- Front-end for SpaceWire Receiver |
-- |
-- This entity samples the input signals DataIn and StrobeIn to detect |
-- valid bit transitions. Received bits are handed to the application. |
-- |
-- Inputs are sampled on the rising edge of the system clock, therefore |
-- the maximum bitrate of the incoming signal must be significantly lower |
-- than system clock frequency. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all; |
use ieee.numeric_std.all; |
|
entity spwrecvfront_generic is |
|
port ( |
-- System clock. |
clk: in std_logic; |
|
-- High to enable receiver; low to disable and reset receiver. |
rxen: in std_logic; |
|
-- High if there has been recent activity on the input lines. |
inact: out std_logic; |
|
-- High if inbits contains a valid received bit. |
-- If inbvalid='1', the application must sample inbits on |
-- the rising edge of clk. |
inbvalid: out std_logic; |
|
-- Received bit |
inbits: out std_logic_vector(0 downto 0); |
|
-- Data In signal from SpaceWire bus. |
spw_di: in std_logic; |
|
-- Strobe In signal from SpaceWire bus. |
spw_si: in std_logic ); |
|
end entity spwrecvfront_generic; |
|
architecture spwrecvfront_arch of spwrecvfront_generic is |
|
-- input flip-flops |
signal s_spwdi1: std_ulogic; |
signal s_spwsi1: std_ulogic; |
signal s_spwdi2: std_ulogic; |
signal s_spwsi2: std_ulogic; |
|
-- data/strobe decoding |
signal s_spwsi3: std_ulogic; |
|
-- output registers |
signal s_inbvalid: std_ulogic; |
signal s_inbit: std_ulogic; |
|
begin |
|
-- drive outputs |
inact <= s_inbvalid; |
inbvalid <= s_inbvalid; |
inbits(0) <= s_inbit; |
|
-- synchronous process |
process (clk) is |
begin |
if rising_edge(clk) then |
|
-- sample input signal |
s_spwdi1 <= spw_di; |
s_spwsi1 <= spw_si; |
|
-- more flip-flops for safe synchronization |
s_spwdi2 <= s_spwdi1; |
s_spwsi2 <= s_spwsi1; |
|
-- keep strobe signal for data/strobe decoding |
s_spwsi3 <= s_spwsi2; |
|
if rxen = '1' then |
-- data/strobe decoding |
s_inbit <= s_spwdi2; |
s_inbvalid <= s_spwdi2 xor s_spwsi2 xor s_inbit xor s_spwsi3; |
else |
-- reset receiver |
s_inbit <= '0'; |
s_inbvalid <= '0'; |
end if; |
|
end if; |
end process; |
|
end architecture spwrecvfront_arch; |
/sim/ghdl/Makefile
0,0 → 1,53
# |
# Makefile for building and running RTL simulation with GHDL. |
# |
# Simulation has been tested with GHDL 0.29. |
# GHDL is available from http://ghdl.free.fr/ |
# |
|
GHDL = ghdl |
RTLDIR = ../../rtl/vhdl |
TBDIR = ../../bench/vhdl |
|
.PHONY: default test_spwlink test_streamtest clean |
|
default: |
@echo "Targets:" |
@echo " make spwlink_tb Build default spwlink testbench" |
@echo " make spwlink_tb_all Build spwlink mega testbench" |
@echo " make test_spwlink Run spwlink mega testbench" |
@echo " make streamtest_tb Build spwstream testbench" |
@echo " make test_streamtest Run spwstream testbench" |
@echo " make clean Remove build files" |
|
SPWLINK_VHDL = $(RTLDIR)/spwpkg.vhd \ |
$(RTLDIR)/spwlink.vhd \ |
$(RTLDIR)/spwrecv.vhd \ |
$(RTLDIR)/spwxmit.vhd \ |
$(RTLDIR)/spwxmit_fast.vhd \ |
$(RTLDIR)/spwrecvfront_generic.vhd \ |
$(RTLDIR)/spwrecvfront_fast.vhd |
|
SPWSTREAM_VHDL = $(SPWLINK_VHDL) \ |
$(RTLDIR)/spwstream.vhd \ |
$(RTLDIR)/spwram.vhd |
|
spwlink_tb: $(TBDIR)/spwlink_tb.vhd $(SPWLINK_VHDL) |
$(GHDL) -c $^ -e spwlink_tb |
|
spwlink_tb_all: $(TBDIR)/spwlink_tb_all.vhd $(TBDIR)/spwlink_tb.vhd $(SPWLINK_VHDL) |
$(GHDL) -c $^ -e spwlink_tb_all |
|
test_spwlink: spwlink_tb_all |
$(GHDL) -r spwlink_tb_all --assert-level=error |
|
streamtest_tb: $(TBDIR)/streamtest_tb.vhd $(RTLDIR)/streamtest.vhd $(SPWSTREAM_VHDL) |
$(GHDL) -c $^ -e streamtest_tb |
|
test_streamtest: streamtest_tb |
$(GHDL) -r streamtest_tb --assert-level=error |
|
clean: |
$(GHDL) --clean |
$(RM) e~spwlink_tb.o e~spwlink_tb_all.o e~streamtest_tb.o |
|
/syn/spwstream_gr-xc3s1500/spwstream.ucf
0,0 → 1,10
|
NET "clk" TNM_NET = "clk" ; |
TIMESPEC "TS_clk" = PERIOD "clk" 13 ns ; |
|
NET "fastclk" TNM_NET = "fastclk" ; |
TIMESPEC "TS_fastclk" = PERIOD "fastclk" 4 ns ; |
|
TIMESPEC "TS_fast_to_sys" = FROM "fastclk" TO "clk" 4 ns ; |
TIMESPEC "TS_sys_to_fast" = FROM "clk" TO "fastclk" 4 ns ; |
|
/syn/spwstream_gr-xc3s1500/spwstream_top.vhd
0,0 → 1,95
library ieee; |
use ieee.std_logic_1164.all, ieee.numeric_std.all; |
use work.spwpkg.all; |
|
entity spwstream_top is |
|
port ( |
clk: in std_logic; |
fastclk: in std_logic; |
rst: in std_logic; |
autostart: in std_logic; |
linkstart: in std_logic; |
linkdis: in std_logic; |
txdivcnt: in std_logic_vector(7 downto 0); |
tick_in: in std_logic; |
ctrl_in: in std_logic_vector(1 downto 0); |
time_in: in std_logic_vector(5 downto 0); |
txwrite: in std_logic; |
txflag: in std_logic; |
txdata: in std_logic_vector(7 downto 0); |
txrdy: out std_logic; |
txhalff: out std_logic; |
tick_out: out std_logic; |
ctrl_out: out std_logic_vector(1 downto 0); |
time_out: out std_logic_vector(5 downto 0); |
rxvalid: out std_logic; |
rxhalff: out std_logic; |
rxflag: out std_logic; |
rxdata: out std_logic_vector(7 downto 0); |
rxread: in std_logic; |
started: out std_logic; |
connecting: out std_logic; |
running: out std_logic; |
errdisc: out std_logic; |
errpar: out std_logic; |
erresc: out std_logic; |
errcred: out std_logic; |
spw_di: in std_logic; |
spw_si: in std_logic; |
spw_do: out std_logic; |
spw_so: out std_logic |
); |
|
end entity spwstream_top; |
|
architecture spwstream_top_arch of spwstream_top is |
|
begin |
|
spwstream_inst: spwstream |
generic map ( |
sysfreq => 60.0e6, |
rximpl => impl_fast, |
rxchunk => 4, |
tximpl => impl_fast, |
rxfifosize_bits => 11, |
txfifosize_bits => 6 ) |
port map ( |
clk => clk, |
rxclk => fastclk, |
txclk => fastclk, |
rst => rst, |
autostart => autostart, |
linkstart => linkstart, |
linkdis => linkdis, |
txdivcnt => txdivcnt, |
tick_in => tick_in, |
ctrl_in => ctrl_in, |
time_in => time_in, |
txwrite => txwrite, |
txflag => txflag, |
txdata => txdata, |
txrdy => txrdy |
, txhalff => txhalff, |
tick_out => tick_out, |
ctrl_out => ctrl_out, |
time_out => time_out, |
rxvalid => rxvalid, |
rxhalff => rxhalff, |
rxflag => rxflag, |
rxdata => rxdata, |
rxread => rxread, |
started => started, |
connecting => connecting, |
running => running, |
errdisc => errdisc, |
errpar => errpar, |
erresc => erresc, |
errcred => errcred, |
spw_di => spw_di, |
spw_si => spw_si, |
spw_do => spw_do, |
spw_so => spw_so ); |
|
end architecture spwstream_top_arch; |
/syn/spwstream_gr-xc3s1500/Makefile
0,0 → 1,290
|
############################################################################### |
## ## |
## project-dependent variables ## |
## ## |
############################################################################### |
|
# The project name. The bit-file that is generated in the end will be named |
# "$(PROJ).bit" |
|
PROJ = spwstream |
|
# The top-level entity to be instantiated |
|
TOPLEVEL = spwstream_top |
|
# The VHDL sources that need to be compiled during synthesis |
|
RTLDIR = ../../rtl/vhdl |
VHDL_SOURCES = spwstream_top.vhd \ |
$(RTLDIR)/spwpkg.vhd \ |
$(RTLDIR)/spwstream.vhd \ |
$(RTLDIR)/spwlink.vhd \ |
$(RTLDIR)/spwram.vhd \ |
$(RTLDIR)/spwrecv.vhd \ |
$(RTLDIR)/spwxmit.vhd \ |
$(RTLDIR)/spwxmit_fast.vhd \ |
$(RTLDIR)/spwrecvfront_generic.vhd \ |
$(RTLDIR)/spwrecvfront_fast.vhd |
|
# Device type: Spartan-3 on Pender XC3S1500 board |
|
FPGA_TYPE = xc3s1500-fg456-4 |
|
# The default target; recommended targets: "bitfile" or "upload" |
|
default : bitfile |
|
UCFFILE = spwstream.ucf |
|
############################################################################### |
## ## |
## miscellaneous project-independent variables & rules ## |
## ## |
############################################################################### |
|
# use this to make most tools quieter |
OPT_INTSTYLE = -intstyle ise |
|
# Phony (non file creating) targets |
|
.PHONY : default clean bitfile |
|
clean : |
$(RM) -rf *~ work dump.xst _ngo 'file graph' xlnx_auto_0_xdb |
$(RM) $(PROJ).xst-script |
$(RM) $(PROJ).lso $(PROJ).prj |
$(RM) $(PROJ).ngc $(PROJ).xst.log $(PROJ).syr $(PROJ).srp $(PROJ).ngr |
$(RM) $(PROJ).ngd $(PROJ).bld |
$(RM) $(PROJ).twx $(PROJ).twr |
$(RM) $(PROJ).pcf $(PROJ)_map.mrp $(PROJ)_map.ncd $(PROJ)_map.ngm |
$(RM) $(PROJ).ncd $(PROJ).pad $(PROJ).par $(PROJ).xpi $(PROJ)_pad.csv $(PROJ)_pad.txt |
$(RM) $(PROJ).bit $(PROJ).bgn $(PROJ).drca |
$(RM) $(PROJ).ptwx $(PROJ).unroutes *.xrpt $(PROJ)_summary.xml $(PROJ)_usage.xml $(PROJ)_map.map |
|
bitfile : $(PROJ).bit |
|
############################################################################### |
# # |
# STAGE 1: "xst" (Xilinx Synthesis Tool) # |
# needs: # |
# # |
# $(PROJ).vhdl # |
# $(PROJ).prj - Project file (created below) # |
# $(PROJ).lso - Library Search Order file (created below) # |
# # |
# created files: # |
# # |
# $(PROJ).ngc - netlist # |
# $(PROJ).ngr - XILINX-XDB 0.1 STUB 0.1 ASCII / XILINX-XDM V1.2e # |
# (optional, depending on the '-rtlview' option) # |
# $(PROJ).xst.log - human-readable synthesis report # |
# (AKA .syr, .srp) # |
# # |
# created directories: # |
# # |
# work # |
# dump.xst # |
# # |
############################################################################### |
|
# Generate a "Library Search Order" file, containing just "work" for now. |
|
$(PROJ).lso : |
@echo "work" > $@ |
|
# Generate a "Project" file, consisting of lines containing each of the |
# VHDL_SOURCES, preceded by "vhdl work". |
|
$(PROJ).prj : |
$(shell echo -n $(VHDL_SOURCES) | \ |
sed 's/\([^ ]\+\) */vhdl work \1\n/g' > $@) |
|
$(PROJ).xst-script : |
@echo "set -tmpdir /tmp" > $@ |
@echo "set -xsthdpdir ." >> $@ |
@echo "run" >> $@ |
@echo "-ifn $(PROJ).prj" >> $@ |
@echo "-ifmt mixed" >> $@ |
@echo "-ofn $(PROJ)" >> $@ |
@echo "-ofmt ngc" >> $@ |
@echo "-p $(FPGA_TYPE)" >> $@ |
@echo "-top $(TOPLEVEL)" >> $@ |
@echo "-opt_mode speed" >> $@ |
@echo "-opt_level 1" >> $@ |
@echo "-iuc no" >> $@ |
@echo "-lso $(PROJ).lso" >> $@ |
@echo "-keep_hierarchy no" >> $@ |
@echo "-glob_opt AllClockNets" >> $@ |
@echo "-rtlview no" >> $@ |
@echo "-read_cores yes" >> $@ |
@echo "-write_timing_constraints yes" >> $@ |
@echo "-cross_clock_analysis no" >> $@ |
# @echo "-hierarchy_separator _" >> $@ |
@echo "-bus_delimiter <>" >> $@ |
@echo "-case maintain" >> $@ |
@echo "-slice_utilization_ratio 100" >> $@ |
# @echo "-verilog2001 yes" >> $@ |
# @echo "-vlgincdir" >> $@ |
@echo "-fsm_extract yes" >> $@ |
@echo "-fsm_encoding auto" >> $@ |
@echo "-fsm_style lut" >> $@ |
@echo "-ram_extract yes" >> $@ |
@echo "-ram_style auto" >> $@ |
@echo "-rom_extract yes" >> $@ |
@echo "-rom_style auto" >> $@ |
@echo "-mux_extract yes" >> $@ |
@echo "-mux_style auto" >> $@ |
@echo "-decoder_extract yes" >> $@ |
@echo "-priority_extract yes" >> $@ |
@echo "-shreg_extract yes" >> $@ |
@echo "-shift_extract yes" >> $@ |
@echo "-xor_collapse yes" >> $@ |
@echo "-resource_sharing yes" >> $@ |
@echo "-mult_style auto" >> $@ |
@echo "-iobuf yes" >> $@ |
@echo "-max_fanout 500" >> $@ |
@echo "-bufg 8" >> $@ |
@echo "-register_duplication yes" >> $@ |
@echo "-equivalent_register_removal yes" >> $@ |
@echo "-register_balancing no" >> $@ |
@echo "-slice_packing yes" >> $@ |
@echo "-optimize_primitives no" >> $@ |
@echo "-iob auto" >> $@ |
|
$(PROJ).ngc $(PROJ).xst.log : $(VHDL_SOURCES) $(PROJ).prj $(PROJ).lso $(PROJ).xst-script |
rm -rf work dump.xst |
xst $(OPT_INTSTYLE) -ifn $(PROJ).xst-script -ofn $(PROJ).xst.log |
rm -rf work dump.xst |
|
############################################################################### |
# # |
# STAGE 2: ngdbuild # |
# needs: # |
# # |
# $(PROJ).ngc # |
# # |
# created files: # |
# # |
# $(PROJ).bld - human-readable build log # |
# $(PROJ).ngd - XILINX-XDB 0.1 STUB 0.1 ASCII / XILINX-XDM V1.2e # |
# # |
# created dir: # |
# _ngo # |
# # |
############################################################################### |
|
$(PROJ).ngd $(PROJ).bld: $(PROJ).ngc $(UCFFILE) |
rm -rf _ngo |
ngdbuild $(OPT_INTSTYLE) -dd _ngo -aul -p $(FPGA_TYPE) $(if $(UCFFILE),-uc $(UCFFILE)) $(PROJ).ngc $(PROJ).ngd |
rm -rf _ngo |
|
############################################################################### |
# # |
# STAGE 3: Mapper # |
# needs: # |
# # |
# $(PROJ).ngd # |
# # |
# created files: # |
# # |
# $(PROJ).pcf - ASCII file # |
# $(PROJ)_map.mrp - human-readable mapping report # |
# $(PROJ)_map.ncd - binary format # |
# $(PROJ)_map.ngm - XILINX-XDB 0.1 STUB 0.1 ASCII / XILINX-XDM V1.2e # |
# # |
# NOTE: # |
# # |
# In order to prevent the make process from terminating on these spurious # |
# problems, we precede the "map" invocation with a hyphen, instructing # |
# make to ignore the return code from "map". # |
# # |
############################################################################### |
|
$(PROJ).pcf $(PROJ)_map.mrp $(PROJ)_map.ncd $(PROJ)_map.ngm: $(PROJ).ngd |
map $(OPT_INTSTYLE) -p $(FPGA_TYPE) -cm area -pr b -c 100 -o $(PROJ)_map.ncd $(PROJ).ngd $(PROJ).pcf |
|
############################################################################### |
# # |
# STAGE 4: Place-and-Route # |
# needs: # |
# # |
# $(PROJ).pcf # |
# $(PROJ)_map.ncd # |
# # |
# created files: # |
# # |
# $(PROJ).ncd - binary file # |
# $(PROJ).pad - ASCII file for import in spreadsheet # |
# $(PROJ).par - human-readable place-and-route report # |
# $(PROJ).xpi - ASCII file # |
# $(PROJ)_pad.csv - human-readable CVS file # |
# $(PROJ)_pad.txt - human-readable file # |
# # |
############################################################################### |
|
$(PROJ).ncd $(PROJ).pad $(PROJ).par $(PROJ).xpi $(PROJ)_pad.csv $(PROJ)_pad.txt: $(PROJ).pcf $(PROJ)_map.ncd |
par -w $(OPT_INTSTYLE) -t 1 $(PROJ)_map.ncd $(PROJ).ncd $(PROJ).pcf |
|
############################################################################### |
# # |
# STAGE 4.5 (optional): trace # |
# needs: # |
# # |
# created files: # |
# # |
############################################################################### |
|
$(PROJ).twr $(PROJ).twx : $(PROJ).ncd $(PROJ).pcf |
trce $(OPT_INTSTYLE) -e 5 -l 5 -u 5 -xml $(PROJ) $(PROJ).ncd -o $(PROJ).twr $(PROJ).pcf |
|
############################################################################### |
# # |
# STAGE 5: Generate BIT-file # |
# needs: # |
# # |
# $(PROJ).ncd # |
# # |
# created files: $(PROJ).bgn $(PROJ).bit $(PROJ).drc # |
# # |
# $(PROJ).bgn - human-readable BitGen report # |
# $(PROJ).drc - human readable DRC report # |
# $(PROJ).bit - binary image file # |
# # |
############################################################################### |
|
# We omit "-g StartUpClk:JtagClk" ; this doesn't work if the image is loaded |
# from a PROM. |
|
OPT_BITGEN = -w \ |
-g DebugBitstream:No \ |
-g Binary:no \ |
-g CRC:Enable \ |
-g ConfigRate:6 \ |
-g CclkPin:PullUp \ |
-g M0Pin:PullUp \ |
-g M1Pin:PullUp \ |
-g M2Pin:PullUp \ |
-g ProgPin:PullUp \ |
-g DonePin:PullUp \ |
-g TckPin:PullUp \ |
-g TdiPin:PullUp \ |
-g TdoPin:PullUp \ |
-g TmsPin:PullUp \ |
-g UnusedPin:PullDown \ |
-g UserID:0xFFFFFFFF \ |
-g DCMShutDown:Disable \ |
-g DONE_cycle:4 \ |
-g GTS_cycle:5 \ |
-g GWE_cycle:6 \ |
-g LCK_cycle:NoWait \ |
-g Match_cycle:Auto \ |
-g Security:None \ |
-g DonePipe:No \ |
-g DriveDone:No |
|
$(PROJ).bit $(PROJ).bgn $(PROJ).drc: $(PROJ).ncd |
bitgen $(OPT_INTSTYLE) $(OPT_BITGEN) $(PROJ).ncd |
|
############################################################################### |
/syn/streamtest_digilent-xc3s200/streamtest.xise
0,0 → 1,388
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> |
<project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema"> |
|
<header> |
<!-- ISE source project file created by Project Navigator. --> |
<!-- --> |
<!-- This file contains project source information including a list of --> |
<!-- project source files, project and process properties. This file, --> |
<!-- along with the project source files, is sufficient to open and --> |
<!-- implement in ISE Project Navigator. --> |
<!-- --> |
<!-- Copyright (c) 1995-2009 Xilinx, Inc. All rights reserved. --> |
</header> |
|
<version xil_pn:ise_version="11.3" xil_pn:schema_version="2"/> |
|
<files> |
<file xil_pn:name="../../rtl/vhdl/spwlink.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="../../rtl/vhdl/spwpkg.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="../../rtl/vhdl/spwram.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="../../rtl/vhdl/spwrecv.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="../../rtl/vhdl/spwrecvfront_fast.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="../../rtl/vhdl/spwrecvfront_generic.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="../../rtl/vhdl/spwstream.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="../../rtl/vhdl/spwxmit.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="../../rtl/vhdl/spwxmit_fast.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="../../rtl/vhdl/streamtest.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="streamtest.ucf" xil_pn:type="FILE_UCF"> |
<association xil_pn:name="Implementation"/> |
</file> |
<file xil_pn:name="streamtest_top.vhd" xil_pn:type="FILE_VHDL"> |
<association xil_pn:name="BehavioralSimulation"/> |
<association xil_pn:name="Implementation"/> |
</file> |
</files> |
|
<properties> |
<property xil_pn:name="Add I/O Buffers" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Allow Logic Optimization Across Hierarchy" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Allow SelectMAP Pins to Persist" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Allow Unexpanded Blocks" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Allow Unmatched LOC Constraints" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Allow Unmatched Timing Group Constraints" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Asynchronous To Synchronous" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Auto Implementation Compile Order" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Auto Implementation Top" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Automatic BRAM Packing" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Automatically Insert glbl Module in the Netlist" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Automatically Run Generate Target PROM/ACE File" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="BRAM Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/> |
<property xil_pn:name="Block RAM Data File" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Bring Out Global Set/Reset Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Bring Out Global Tristate Net as a Port" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Bus Delimiter" xil_pn:value="<>" xil_pn:valueState="default"/> |
<property xil_pn:name="CLB Pack Factor Percentage" xil_pn:value="100" xil_pn:valueState="default"/> |
<property xil_pn:name="Case" xil_pn:value="Maintain" xil_pn:valueState="default"/> |
<property xil_pn:name="Case Implementation Style" xil_pn:value="None" xil_pn:valueState="default"/> |
<property xil_pn:name="Change Device Speed To" xil_pn:value="-4" xil_pn:valueState="default"/> |
<property xil_pn:name="Change Device Speed To Post Trace" xil_pn:value="-4" xil_pn:valueState="default"/> |
<property xil_pn:name="Combinatorial Logic Optimization" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Command line syntax" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Compile EDK Simulation Library" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Compile SIMPRIM (Timing) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Compile UNISIM (Functional) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Compile XilinxCoreLib (CORE Generator) Simulation Library" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Compile for HDL Debugging" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Compiled Library Directory" xil_pn:value="$XILINX/<language>/<simulator>" xil_pn:valueState="default"/> |
<property xil_pn:name="Configuration Clk (Configuration Pins)" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="Configuration Pin Done" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="Configuration Pin HSWAPEN" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="Configuration Pin M0" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="Configuration Pin M1" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="Configuration Pin M2" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="Configuration Pin Program" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="Configuration Rate" xil_pn:value="Default (6)" xil_pn:valueState="default"/> |
<property xil_pn:name="Constraints Entry" xil_pn:value="Constraints Editor" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Constraints Interaction Report File" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Constraints Interaction Report File Post Trace" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Cores Search Directories" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Correlate Output to Input Design" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Create ASCII Configuration File" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Create Binary Configuration File" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Create Bit File" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Create I/O Pads from Ports" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Create IEEE 1532 Configuration File" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Create Logic Allocation File" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Create Mask File" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Create ReadBack Data Files" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Cross Clock Analysis" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Custom Project Filename Behavioral" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Custom Project Filename Post-Route" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Custom Simulation Command File" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Custom Simulation Command File Par" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Custom Waveform Configuration File Behav" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Custom Waveform Configuration File Par" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="DCI Update Mode" xil_pn:value="As Required" xil_pn:valueState="default"/> |
<property xil_pn:name="Decoder Extraction" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Delay Values To Be Read from SDF" xil_pn:value="Setup Time" xil_pn:valueState="default"/> |
<property xil_pn:name="Device" xil_pn:value="xc3s200" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Device Family" xil_pn:value="Spartan3" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Device Speed Grade/Select ABS Minimum" xil_pn:value="-4" xil_pn:valueState="default"/> |
<property xil_pn:name="Display Incremental Messages" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Do Not Escape Signal and Instance Names in Netlist" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Done (Output Events)" xil_pn:value="Default (4)" xil_pn:valueState="default"/> |
<property xil_pn:name="Drive Done Pin High" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Editor" xil_pn:value="ISE Text Editor" xil_pn:valueState="default"/> |
<property xil_pn:name="Enable BitStream Compression" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Enable Cyclic Redundancy Checking (CRC)" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Enable Debugging of Serial Mode BitStream" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Enable Enhanced Design Summary" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Enable Internal Done Pipe" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Enable Message Filtering" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Enable Outputs (Output Events)" xil_pn:value="Default (5)" xil_pn:valueState="default"/> |
<property xil_pn:name="Equivalent Register Removal XST" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Exclude Compilation of Deprecated EDK Cores" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Exclude Compilation of EDK Sub-Libraries" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Extra Effort" xil_pn:value="None" xil_pn:valueState="default"/> |
<property xil_pn:name="Extra Effort (Highest PAR level only)" xil_pn:value="None" xil_pn:valueState="default"/> |
<property xil_pn:name="FPGA Start-Up Clock" xil_pn:value="CCLK" xil_pn:valueState="default"/> |
<property xil_pn:name="FSM Encoding Algorithm" xil_pn:value="Auto" xil_pn:valueState="default"/> |
<property xil_pn:name="FSM Style" xil_pn:value="LUT" xil_pn:valueState="default"/> |
<property xil_pn:name="Filter Files From Compile Order" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Fitter Report Format" xil_pn:value="HTML" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Flatten Output Netlist" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Flow Debug Level" xil_pn:value="0" xil_pn:valueState="default"/> |
<property xil_pn:name="Functional Model Target Language ArchWiz" xil_pn:value="VHDL" xil_pn:valueState="default"/> |
<property xil_pn:name="Functional Model Target Language Coregen" xil_pn:value="VHDL" xil_pn:valueState="default"/> |
<property xil_pn:name="Functional Model Target Language Schematic" xil_pn:value="VHDL" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Architecture Only (No Entity Declaration)" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Asynchronous Delay Report" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Clock Region Report" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Constraints Interaction Report" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Constraints Interaction Report Post Trace" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Datasheet Section" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Datasheet Section Post Trace" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Detailed MAP Report" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Multiple Hierarchical Netlist Files" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Post-Place & Route Power Report" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Post-Place & Route Simulation Model" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate RTL Schematic" xil_pn:value="Yes" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate SAIF File for Power Optimization/Estimation Par" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Testbench File" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Timegroups Section" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generate Timegroups Section Post Trace" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Generics, Parameters" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Global Optimization Goal" xil_pn:value="AllClockNets" xil_pn:valueState="default"/> |
<property xil_pn:name="Global Set/Reset Port Name" xil_pn:value="GSR_PORT" xil_pn:valueState="default"/> |
<property xil_pn:name="Global Tristate Port Name" xil_pn:value="GTS_PORT" xil_pn:valueState="default"/> |
<property xil_pn:name="HDL INI File" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Hierarchy Separator" xil_pn:value="/" xil_pn:valueState="default"/> |
<property xil_pn:name="ISim UUT Instance Name" xil_pn:value="UUT" xil_pn:valueState="default"/> |
<property xil_pn:name="Ignore User Timing Constraints Map" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Ignore User Timing Constraints Par" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Implementation Top" xil_pn:value="Architecture|streamtest_top|streamtest_top_arch" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Implementation Top Instance Path" xil_pn:value="/streamtest_top" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Include 'uselib Directive in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Include SIMPRIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Include UNISIM Models in Verilog File" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Include sdf_annotate task in Verilog File" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Incremental Compilation" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Input TCL Command Script" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Insert Buffers to Prevent Pulse Swallowing" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Instantiation Template Target Language Xps" xil_pn:value="VHDL" xil_pn:valueState="default"/> |
<property xil_pn:name="JTAG Pin TCK" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="JTAG Pin TDI" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="JTAG Pin TDO" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="JTAG Pin TMS" xil_pn:value="Pull Up" xil_pn:valueState="default"/> |
<property xil_pn:name="Keep Hierarchy" xil_pn:value="No" xil_pn:valueState="default"/> |
<property xil_pn:name="Language" xil_pn:value="VHDL" xil_pn:valueState="default"/> |
<property xil_pn:name="Last Applied Goal" xil_pn:value="Balanced" xil_pn:valueState="default"/> |
<property xil_pn:name="Last Applied Strategy" xil_pn:value="Xilinx Default (unlocked)" xil_pn:valueState="default"/> |
<property xil_pn:name="Last Unlock Status" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Library Search Order" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Load Physical Constraints File" xil_pn:value="Default" xil_pn:valueState="default"/> |
<property xil_pn:name="Load Setting File" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Load Simulation File" xil_pn:value="Default" xil_pn:valueState="default"/> |
<property xil_pn:name="Logical Shifter Extraction" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Macro Search Path" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Manual Implementation Compile Order" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Map Effort Level" xil_pn:value="Standard" xil_pn:valueState="default"/> |
<property xil_pn:name="Map Slice Logic into Unused Block RAMs" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Max Fanout" xil_pn:value="500" xil_pn:valueState="default"/> |
<property xil_pn:name="Maximum Number of Lines in Report" xil_pn:value="1000" xil_pn:valueState="default"/> |
<property xil_pn:name="Move First Flip-Flop Stage" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Move Last Flip-Flop Stage" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Multiplier Style" xil_pn:value="Auto" xil_pn:valueState="default"/> |
<property xil_pn:name="Mux Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/> |
<property xil_pn:name="Mux Style" xil_pn:value="Auto" xil_pn:valueState="default"/> |
<property xil_pn:name="Netlist Hierarchy" xil_pn:value="As Optimized" xil_pn:valueState="default"/> |
<property xil_pn:name="Netlist Translation Type" xil_pn:value="Timestamp" xil_pn:valueState="default"/> |
<property xil_pn:name="Number of Clock Buffers" xil_pn:value="8" xil_pn:valueState="default"/> |
<property xil_pn:name="Number of Paths in Error/Verbose Report" xil_pn:value="3" xil_pn:valueState="default"/> |
<property xil_pn:name="Number of Paths in Error/Verbose Report Post Trace" xil_pn:value="3" xil_pn:valueState="default"/> |
<property xil_pn:name="Optimization Effort" xil_pn:value="Normal" xil_pn:valueState="default"/> |
<property xil_pn:name="Optimization Goal" xil_pn:value="Speed" xil_pn:valueState="default"/> |
<property xil_pn:name="Optimization Strategy (Cover Mode)" xil_pn:value="Area" xil_pn:valueState="default"/> |
<property xil_pn:name="Optimize Instantiated Primitives" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Other Bitgen Command Line Options" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Other Compiler Options" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Other Compiler Options Par" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Other Compxlib Command Line Options" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Other Map Command Line Options" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Other NETGEN Command Line Options" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Other Ngdbuild Command Line Options" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Other Place & Route Command Line Options" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Other XPWR Command Line Options" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Other XST Command Line Options" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Output Extended Identifiers" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Output File Name" xil_pn:value="streamtest_top" xil_pn:valueState="default"/> |
<property xil_pn:name="Overwrite Compiled Libraries" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Pack I/O Registers into IOBs" xil_pn:value="Auto" xil_pn:valueState="default"/> |
<property xil_pn:name="Pack I/O Registers/Latches into IOBs" xil_pn:value="For Inputs and Outputs" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Package" xil_pn:value="ft256" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Path Used in sdf_annotate task" xil_pn:value="Default" xil_pn:valueState="default"/> |
<property xil_pn:name="Path(s) to Previously Compiled EDK Libraries" xil_pn:value="Search in Path" xil_pn:valueState="default"/> |
<property xil_pn:name="Perform Advanced Analysis" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Perform Advanced Analysis Post Trace" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Perform Timing-Driven Packing and Placement" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Place & Route Effort Level (Overall)" xil_pn:value="Standard" xil_pn:valueState="default"/> |
<property xil_pn:name="Place And Route Mode" xil_pn:value="Normal Place and Route" xil_pn:valueState="default"/> |
<property xil_pn:name="Placer Effort Level (Overrides Overall Level)" xil_pn:value="None" xil_pn:valueState="default"/> |
<property xil_pn:name="Port to be used" xil_pn:value="Auto - default" xil_pn:valueState="default"/> |
<property xil_pn:name="Post Map Simulation Model Name" xil_pn:value="streamtest_top_map.vhd" xil_pn:valueState="default"/> |
<property xil_pn:name="Post Place & Route Simulation Model Name" xil_pn:value="streamtest_top_timesim.vhd" xil_pn:valueState="default"/> |
<property xil_pn:name="Post Synthesis Simulation Model Name" xil_pn:value="streamtest_top_synthesis.vhd" xil_pn:valueState="default"/> |
<property xil_pn:name="Post Translate Simulation Model Name" xil_pn:value="streamtest_top_translate.vhd" xil_pn:valueState="default"/> |
<property xil_pn:name="Power Activity File Map" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Power Activity File Par" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Power Reduction Map" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Power Reduction Par" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Preferred Language" xil_pn:value="VHDL" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Priority Encoder Extraction" xil_pn:value="Yes" xil_pn:valueState="default"/> |
<property xil_pn:name="Produce Advanced Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Produce Verbose Report" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Project Description" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Property Specification in Project File" xil_pn:value="Store all values" xil_pn:valueState="default"/> |
<property xil_pn:name="RAM Extraction" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="RAM Style" xil_pn:value="Auto" xil_pn:valueState="default"/> |
<property xil_pn:name="ROM Extraction" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="ROM Style" xil_pn:value="Auto" xil_pn:valueState="default"/> |
<property xil_pn:name="Read Cores" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Regenerate Core" xil_pn:value="Under Current Project Setting" xil_pn:valueState="default"/> |
<property xil_pn:name="Register Balancing" xil_pn:value="No" xil_pn:valueState="default"/> |
<property xil_pn:name="Register Duplication" xil_pn:value="Off" xil_pn:valueState="default"/> |
<property xil_pn:name="Register Duplication Xst" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Release Write Enable (Output Events)" xil_pn:value="Default (6)" xil_pn:valueState="default"/> |
<property xil_pn:name="Rename Design Instance in Testbench File to" xil_pn:value="UUT" xil_pn:valueState="default"/> |
<property xil_pn:name="Rename Top Level Architecture To" xil_pn:value="Structure" xil_pn:valueState="default"/> |
<property xil_pn:name="Rename Top Level Entity to" xil_pn:value="streamtest_top" xil_pn:valueState="default"/> |
<property xil_pn:name="Rename Top Level Module To" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Report Fastest Path(s) in Each Constraint" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Report Fastest Path(s) in Each Constraint Post Trace" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Report Paths by Endpoint" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Report Paths by Endpoint Post Trace" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Report Type" xil_pn:value="Verbose Report" xil_pn:valueState="default"/> |
<property xil_pn:name="Report Type Post Trace" xil_pn:value="Verbose Report" xil_pn:valueState="default"/> |
<property xil_pn:name="Report Unconstrained Paths" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Report Unconstrained Paths Post Trace" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Reset DCM if SHUTDOWN & AGHIGH performed" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Reset On Configuration Pulse Width" xil_pn:value="100" xil_pn:valueState="default"/> |
<property xil_pn:name="Resource Sharing" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Retain Hierarchy" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Router Effort Level (Overrides Overall Level)" xil_pn:value="None" xil_pn:valueState="default"/> |
<property xil_pn:name="Run Design Rules Checker (DRC)" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Run for Specified Time" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Run for Specified Time Par" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="SAIF File Name ISim" xil_pn:value="xpower_time_sim.saif" xil_pn:valueState="default"/> |
<property xil_pn:name="SDK Export Directory" xil_pn:value="SDK_Export" xil_pn:valueState="default"/> |
<property xil_pn:name="Safe Implementation" xil_pn:value="Yes" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Security" xil_pn:value="Enable Readback and Reconfiguration" xil_pn:valueState="default"/> |
<property xil_pn:name="Selected Simulation Root Source Node Behavioral" xil_pn:value="Architecture|streamtest_top|streamtest_top_arch" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Selected Simulation Root Source Node Post-Route" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Selected Simulation Source Node" xil_pn:value="UUT" xil_pn:valueState="default"/> |
<property xil_pn:name="Setting Output File" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Shift Register Extraction" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Show All Models" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Simulation Model Target" xil_pn:value="VHDL" xil_pn:valueState="default"/> |
<property xil_pn:name="Simulation Run Time ISim" xil_pn:value="1000 ns" xil_pn:valueState="default"/> |
<property xil_pn:name="Simulation Run Time Par" xil_pn:value="1000 ns" xil_pn:valueState="default"/> |
<property xil_pn:name="Simulator" xil_pn:value="ISim (VHDL/Verilog)" xil_pn:valueState="default"/> |
<property xil_pn:name="Simulator Path" xil_pn:value="Search in Path" xil_pn:valueState="default"/> |
<property xil_pn:name="Slice Packing" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Slice Utilization Ratio" xil_pn:value="100" xil_pn:valueState="default"/> |
<property xil_pn:name="Smart Guide File Name" xil_pn:value="streamtest_top_guide.ncd" xil_pn:valueState="default"/> |
<property xil_pn:name="Specify 'define Macro Name and Value" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Specify Search Directories for 'Include" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Specify Source Libraries Path" xil_pn:value="Search in Path" xil_pn:valueState="default"/> |
<property xil_pn:name="Specify Top Level Instance Names Behavioral" xil_pn:value="streamtest_top" xil_pn:valueState="default"/> |
<property xil_pn:name="Specify Top Level Instance Names Post-Route" xil_pn:value="Default" xil_pn:valueState="default"/> |
<property xil_pn:name="Speed Grade" xil_pn:value="-4" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Stamp Timing Model Filename" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Starting Placer Cost Table (1-100) Map" xil_pn:value="1" xil_pn:valueState="default"/> |
<property xil_pn:name="Starting Placer Cost Table (1-100) Par" xil_pn:value="1" xil_pn:valueState="default"/> |
<property xil_pn:name="Synthesis Constraints File" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Synthesis Tool" xil_pn:value="XST (VHDL/Verilog)" xil_pn:valueState="default"/> |
<property xil_pn:name="Target UCF File Name" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Timing Mode Map" xil_pn:value="Non Timing Driven" xil_pn:valueState="default"/> |
<property xil_pn:name="Timing Mode Par" xil_pn:value="Performance Evaluation" xil_pn:valueState="default"/> |
<property xil_pn:name="Top-Level Module Name in Output Netlist" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Top-Level Source Type" xil_pn:value="HDL" xil_pn:valueState="default"/> |
<property xil_pn:name="Trim Unconnected Signals" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Tristate On Configuration Pulse Width" xil_pn:value="0" xil_pn:valueState="default"/> |
<property xil_pn:name="Unused IOB Pins" xil_pn:value="Pull Down" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Bonded I/Os" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Clock Enable" xil_pn:value="Yes" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Custom Project File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Custom Project File Post-Route" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Custom Simulation Command File Behavioral" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Custom Simulation Command File Par" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Custom Waveform Configuration File Behav" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Custom Waveform Configuration File Par" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Use LOC Constraints" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Use RLOC Constraints" xil_pn:value="Yes" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Smart Guide" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Synchronous Reset" xil_pn:value="Yes" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Synchronous Set" xil_pn:value="Yes" xil_pn:valueState="default"/> |
<property xil_pn:name="Use Synthesis Constraints File" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="User Browsed Strategy Files" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="User Rules File for Netlister Launcher" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="UserID Code (8 Digit Hexadecimal)" xil_pn:value="0xFFFFFFFF" xil_pn:valueState="default"/> |
<property xil_pn:name="Value Range Check" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="Verilog 2001 Xst" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="Verilog Include Directories" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Verilog Macros" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Wait for DCI Match (Output Events) virtex2" xil_pn:value="Auto" xil_pn:valueState="default"/> |
<property xil_pn:name="Wait for DLL Lock (Output Events)" xil_pn:value="3" xil_pn:valueState="non-default"/> |
<property xil_pn:name="Waveform Database Filename Behavioral" xil_pn:value="streamtest_top_isim_beh.wdb" xil_pn:valueState="default"/> |
<property xil_pn:name="Waveform Database Filename Post-Route" xil_pn:value="top_isim_par.wdb" xil_pn:valueState="default"/> |
<property xil_pn:name="Work Directory" xil_pn:value="xst" xil_pn:valueState="default"/> |
<property xil_pn:name="Working Directory" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="Write Timing Constraints" xil_pn:value="false" xil_pn:valueState="default"/> |
<property xil_pn:name="XOR Collapsing" xil_pn:value="true" xil_pn:valueState="default"/> |
<property xil_pn:name="iMPACT Project File" xil_pn:value="Default" xil_pn:valueState="default"/> |
<!-- --> |
<!-- The following properties are for internal use only. These should not be modified.--> |
<!-- --> |
<property xil_pn:name="PROP_BehavioralSimTop" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="PROP_DesignName" xil_pn:value="streamtest" xil_pn:valueState="non-default"/> |
<property xil_pn:name="PROP_DevFamilyPMName" xil_pn:value="spartan3" xil_pn:valueState="default"/> |
<property xil_pn:name="PROP_PartitionCreateDelete" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="PROP_PartitionForcePlacement" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="PROP_PartitionForceSynth" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="PROP_PartitionForceTranslate" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="PROP_PostMapSimTop" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="PROP_PostParSimTop" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="PROP_PostSynthSimTop" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="PROP_PostXlateSimTop" xil_pn:value="" xil_pn:valueState="default"/> |
<property xil_pn:name="PROP_intWorkingDirLocWRTProjDir" xil_pn:value="Same" xil_pn:valueState="non-default"/> |
<property xil_pn:name="PROP_intWorkingDirUsed" xil_pn:value="No" xil_pn:valueState="non-default"/> |
</properties> |
|
<bindings/> |
|
<libraries/> |
|
<partitions/> |
|
</project> |
/syn/streamtest_digilent-xc3s200/streamtest.ucf
0,0 → 1,43
# Constraints for Digilent XC3S200 board. |
|
# Board clock, 50 MHz = 20 ns nominal, - 2 ns margin = 18 ns |
NET "clk50" TNM_NET = "clk50" ; |
TIMESPEC "TS_clk" = PERIOD "clk50" 18.0 ns ; |
|
# Paths between fastclk and sysclk must be constrained to fastclk period. |
# fastclk = 200 MHz = 5 ns nominal, - 1 ns margin = 4 ns |
NET "sysclk" TNM_NET = "sysclk" ; |
NET "fastclk" TNM_NET = "fastclk" ; |
TIMESPEC "TS_fast_to_sys" = FROM "fastclk" TO "sysclk" 4 ns ; |
TIMESPEC "TS_sys_to_fast" = FROM "sysclk" TO "fastclk" 4 ns ; |
|
NET "clk50" LOC = "T9" ; |
NET "led(0)" LOC = "K12" | DRIVE = 6 ; |
NET "led(1)" LOC = "P14" | DRIVE = 6 ; |
NET "led(2)" LOC = "L12" | DRIVE = 6 ; |
NET "led(3)" LOC = "N14" | DRIVE = 6 ; |
NET "led(4)" LOC = "P13" | DRIVE = 6 ; |
NET "led(5)" LOC = "N12" | DRIVE = 6 ; |
NET "led(6)" LOC = "P12" | DRIVE = 6 ; |
NET "led(7)" LOC = "P11" | DRIVE = 6 ; |
NET "button(0)" LOC = "M13" ; |
NET "button(1)" LOC = "M14" ; |
NET "button(2)" LOC = "L13" ; |
NET "button(3)" LOC = "L14" ; |
NET "switch(0)" LOC = "F12" ; |
NET "switch(1)" LOC = "G12" ; |
NET "switch(2)" LOC = "H14" ; |
NET "switch(3)" LOC = "H13" ; |
NET "switch(4)" LOC = "J14" ; |
NET "switch(5)" LOC = "J13" ; |
NET "switch(6)" LOC = "K14" ; |
NET "switch(7)" LOC = "K13" ; |
NET "spw_di_p" LOC = "B5" ; # | IOSTANDARD = LVDS_25; |
NET "spw_di_n" LOC = "C5" ; # | IOSTANDARD = LVDS_25; |
NET "spw_si_p" LOC = "D6" ; # | IOSTANDARD = LVDS_25; |
NET "spw_si_n" LOC = "E6" ; # | IOSTANDARD = LVDS_25; |
NET "spw_do_p" LOC = "B6" ; # | IOSTANDARD = LVDS_25; |
NET "spw_do_n" LOC = "C6" ; # | IOSTANDARD = LVDS_25; |
NET "spw_so_p" LOC = "D7" ; # | IOSTANDARD = LVDS_25; |
NET "spw_so_n" LOC = "E7" ; # | IOSTANDARD = LVDS_25; |
|
/syn/streamtest_digilent-xc3s200/streamtest_top.vhd
0,0 → 1,253
-- |
-- Test of spwstream on Digilent XC3S200 board. |
-- |
-- LED 0 = link started |
-- LED 1 = link connecting |
-- LED 2 = link run |
-- LED 3 = link error (sticky until clear button) |
-- LED 4 = gotdata |
-- LED 5 = off |
-- LED 6 = data error (sticky until reset) |
-- LED 7 = time code error (sticky until reset) |
-- |
-- Button 0 = reset |
-- Button 1 = clear LED 3 |
-- |
-- Switch 0 = link autostart |
-- Switch 1 = link start |
-- Switch 2 = link disable |
-- Switch 3 = send data and time codes |
-- Switch 4-7 = bits 0-3 of tx bit rate scale factor |
-- |
-- SpaceWire signals on A2 expansion connector: |
-- Data In pos,neg = B5,C5 = pin 19,6 |
-- Strobe In pos,neg = D6,E6 = pin 7,4 |
-- Data Out pos,neg = B6,C6 = pin 21,8 |
-- Strobe Out pos,neg = D7,E7 = pin 11,9 |
-- |
-- Note: these are not true LVDS signals; they are configured as LVDS25 |
-- but powered from 3.3V instead of 2.5V, not differentially routed and |
-- not properly terminated. |
-- |
-- The SpaceWire port should be looped back to itself with wires from |
-- outputs to corresponding inputs. |
-- |
|
library ieee; |
use ieee.std_logic_1164.all, ieee.numeric_std.all; |
library unisim; |
use unisim.vcomponents.all; |
use work.spwpkg.all; |
|
entity streamtest_top is |
|
port ( |
clk50: in std_logic; |
button: in std_logic_vector(3 downto 0); |
switch: in std_logic_vector(7 downto 0); |
led: out std_logic_vector(7 downto 0); |
spw_di_p: in std_logic; |
spw_di_n: in std_logic; |
spw_si_p: in std_logic; |
spw_si_n: in std_logic; |
spw_do_p: out std_logic; |
spw_do_n: out std_logic; |
spw_so_p: out std_logic; |
spw_so_n: out std_logic ); |
|
end entity streamtest_top; |
|
architecture streamtest_top_arch of streamtest_top is |
|
-- Clock generation. |
signal boardclk: std_logic; |
signal sysclk: std_logic; |
signal fastclk: std_logic; |
|
-- Synchronize buttons |
signal s_resetbtn: std_logic := '0'; |
signal s_clearbtn: std_logic := '0'; |
|
-- Sticky LED |
signal s_linkerrorled: std_logic := '0'; |
|
-- Interface signals. |
signal s_rst: std_logic := '1'; |
signal s_linkstart: std_logic := '0'; |
signal s_autostart: std_logic := '0'; |
signal s_linkdisable: std_logic := '0'; |
signal s_senddata: std_logic := '0'; |
signal s_txdivcnt: std_logic_vector(7 downto 0) := "00000000"; |
signal s_linkstarted: std_logic; |
signal s_linkconnecting: std_logic; |
signal s_linkrun: std_logic; |
signal s_linkerror: std_logic; |
signal s_gotdata: std_logic; |
signal s_dataerror: std_logic; |
signal s_tickerror: std_logic; |
signal s_spwdi: std_logic; |
signal s_spwsi: std_logic; |
signal s_spwdo: std_logic; |
signal s_spwso: std_logic; |
|
-- Make clock nets visible to UCF file. |
attribute KEEP: string; |
attribute KEEP of sysclk: signal is "SOFT"; |
attribute KEEP of fastclk: signal is "SOFT"; |
|
component streamtest is |
generic ( |
sysfreq: real; |
tickdiv: integer range 12 to 24 := 20; |
rximpl: spw_implementation_type := impl_generic; |
rxchunk: integer range 1 to 4 := 1; |
tximpl: spw_implementation_type := impl_generic; |
rxfifosize_bits: integer range 6 to 14 := 11; |
txfifosize_bits: integer range 2 to 14 := 11 ); |
port ( |
clk: in std_logic; |
rxclk: in std_logic; |
txclk: in std_logic; |
rst: in std_logic; |
linkstart: in std_logic; |
autostart: in std_logic; |
linkdisable: in std_logic; |
senddata: in std_logic; |
sendtick: in std_logic; |
txdivcnt: in std_logic_vector(7 downto 0); |
linkstarted: out std_logic; |
linkconnecting: out std_logic; |
linkrun: out std_logic; |
linkerror: out std_logic; |
gotdata: out std_logic; |
dataerror: out std_logic; |
tickerror: out std_logic; |
spw_di: in std_logic; |
spw_si: in std_logic; |
spw_do: out std_logic; |
spw_so: out std_logic ); |
end component; |
|
begin |
|
-- Buffer incoming clock. |
bufg0: BUFG port map ( I => clk50, O => boardclk ); |
|
-- Generate 60 MHz system clock. |
dcm0: DCM |
generic map ( |
CLKFX_DIVIDE => 5, |
CLKFX_MULTIPLY => 6, |
CLK_FEEDBACK => "NONE", |
CLKIN_DIVIDE_BY_2 => false, |
CLKIN_PERIOD => 20.0, |
CLKOUT_PHASE_SHIFT => "NONE", |
DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", |
DFS_FREQUENCY_MODE => "LOW", |
DUTY_CYCLE_CORRECTION => true, |
STARTUP_WAIT => true ) |
port map ( |
CLKIN => boardclk, |
RST => '0', |
CLKFX => sysclk ); |
|
-- Generate 200 MHz fast clock. |
dcm1: DCM |
generic map ( |
CLKFX_DIVIDE => 1, |
CLKFX_MULTIPLY => 4, |
CLK_FEEDBACK => "NONE", |
CLKIN_DIVIDE_BY_2 => false, |
CLKIN_PERIOD => 20.0, |
CLKOUT_PHASE_SHIFT => "NONE", |
DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS", |
DFS_FREQUENCY_MODE => "LOW", |
DUTY_CYCLE_CORRECTION => true, |
STARTUP_WAIT => true ) |
port map ( |
CLKIN => boardclk, |
RST => '0', |
CLKFX => fastclk ); |
|
-- Streamtest instance |
streamtest_inst: streamtest |
generic map ( |
sysfreq => 60.0e6, |
tickdiv => 22, |
rximpl => impl_fast, |
rxchunk => 4, |
tximpl => impl_fast, |
rxfifosize_bits => 11, |
txfifosize_bits => 10 ) |
port map ( |
clk => sysclk, |
rxclk => fastclk, |
txclk => fastclk, |
rst => s_rst, |
linkstart => s_linkstart, |
autostart => s_autostart, |
linkdisable => s_linkdisable, |
senddata => s_senddata, |
sendtick => s_senddata, |
txdivcnt => s_txdivcnt, |
linkstarted => s_linkstarted, |
linkconnecting => s_linkconnecting, |
linkrun => s_linkrun, |
linkerror => s_linkerror, |
gotdata => s_gotdata, |
dataerror => s_dataerror, |
tickerror => s_tickerror, |
spw_di => s_spwdi, |
spw_si => s_spwsi, |
spw_do => s_spwdo, |
spw_so => s_spwso ); |
|
-- LVDS buffers |
spwdi_pad: IBUFDS |
generic map ( IOSTANDARD => "LVDS_25" ) |
port map ( O => s_spwdi, I => spw_di_p, IB => spw_di_n ); |
spwsi_pad: IBUFDS |
generic map ( IOSTANDARD => "LVDS_25" ) |
port map ( O => s_spwsi, I => spw_si_p, IB => spw_si_n ); |
spwdo_pad: OBUFDS |
generic map ( IOSTANDARD => "LVDS_25" ) |
port map ( O => spw_do_p, OB => spw_do_n, I => s_spwdo ); |
spwso_pad: OBUFDS |
generic map ( IOSTANDARD => "LVDS_25" ) |
port map ( O => spw_so_p, OB => spw_so_n, I => s_spwso ); |
|
process (sysclk) is |
begin |
if rising_edge(sysclk) then |
|
-- Synchronize buttons |
s_resetbtn <= button(0); |
s_rst <= s_resetbtn; |
s_clearbtn <= button(1); |
|
-- Synchronize switch settings |
s_autostart <= switch(0); |
s_linkstart <= switch(1); |
s_linkdisable <= switch(2); |
s_senddata <= switch(3); |
s_txdivcnt(3 downto 0) <= switch(7 downto 4); |
|
-- Sticky link error LED |
s_linkerrorled <= (s_linkerrorled or s_linkerror) and |
(not s_clearbtn) and |
(not s_resetbtn); |
|
-- Drive LEDs |
led(0) <= s_linkstarted; |
led(1) <= s_linkconnecting; |
led(2) <= s_linkrun; |
led(3) <= s_linkerrorled; |
led(4) <= s_gotdata; |
led(5) <= '0'; |
led(6) <= s_dataerror; |
led(7) <= s_tickerror; |
|
end if; |
end process; |
|
end architecture streamtest_top_arch; |
/syn/streamtest_digilent-xc3s200/Makefile
0,0 → 1,296
|
############################################################################### |
## ## |
## project-dependent variables ## |
## ## |
############################################################################### |
|
# The project name. The bit-file that is generated in the end will be named |
# "$(PROJ).bit" |
|
PROJ = streamtest |
|
# The top-level entity to be instantiated |
|
TOPLEVEL = streamtest_top |
|
# The VHDL sources that need to be compiled during synthesis |
|
RTLDIR = ../../rtl/vhdl |
VHDL_SOURCES = streamtest_top.vhd \ |
$(RTLDIR)/streamtest.vhd \ |
$(RTLDIR)/spwpkg.vhd \ |
$(RTLDIR)/spwstream.vhd \ |
$(RTLDIR)/spwlink.vhd \ |
$(RTLDIR)/spwram.vhd \ |
$(RTLDIR)/spwrecv.vhd \ |
$(RTLDIR)/spwxmit.vhd \ |
$(RTLDIR)/spwxmit_fast.vhd \ |
$(RTLDIR)/spwrecvfront_generic.vhd \ |
$(RTLDIR)/spwrecvfront_fast.vhd |
|
# Device type: Spartan-3 200 on Digilent board |
|
FPGA_TYPE = xc3s200-ft256-4 |
|
# The default target; recommended targets: "bitfile" or "upload" |
|
default : bitfile |
|
UCFFILE = streamtest.ucf |
|
############################################################################### |
## ## |
## miscellaneous project-independent variables & rules ## |
## ## |
############################################################################### |
|
# use this to make most tools quieter |
OPT_INTSTYLE = -intstyle ise |
|
# Phony (non file creating) targets |
|
.PHONY : default clean bitfile |
|
clean : |
$(RM) -rf *~ work dump.xst _ngo 'file graph' xlnx_auto_0_xdb |
$(RM) $(PROJ).xst-script |
$(RM) $(PROJ).lso $(PROJ).prj |
$(RM) $(PROJ).ngc $(PROJ).xst.log $(PROJ).syr $(PROJ).srp $(PROJ).ngr |
$(RM) $(PROJ).ngd $(PROJ).bld |
$(RM) $(PROJ).twx $(PROJ).twr |
$(RM) $(PROJ).pcf $(PROJ)_map.mrp $(PROJ)_map.ncd $(PROJ)_map.ngm |
$(RM) $(PROJ).ncd $(PROJ).pad $(PROJ).par $(PROJ).xpi $(PROJ)_pad.csv $(PROJ)_pad.txt |
$(RM) $(PROJ).bit $(PROJ).bgn $(PROJ).drc |
$(RM) $(PROJ).ptwx $(PROJ).unroutes *.xrpt $(PROJ)_summary.xml $(PROJ)_usage.xml $(PROJ)_map.map |
|
bitfile : $(PROJ).bit |
|
############################################################################### |
# # |
# STAGE 1: "xst" (Xilinx Synthesis Tool) # |
# needs: # |
# # |
# $(PROJ).vhdl # |
# $(PROJ).prj - Project file (created below) # |
# $(PROJ).lso - Library Search Order file (created below) # |
# # |
# created files: # |
# # |
# $(PROJ).ngc - netlist # |
# $(PROJ).ngr - XILINX-XDB 0.1 STUB 0.1 ASCII / XILINX-XDM V1.2e # |
# (optional, depending on the '-rtlview' option) # |
# $(PROJ).xst.log - human-readable synthesis report # |
# (AKA .syr, .srp) # |
# # |
# created directories: # |
# # |
# work # |
# dump.xst # |
# # |
############################################################################### |
|
# Generate a "Library Search Order" file, containing just "work" for now. |
|
$(PROJ).lso : |
@echo "work" > $@ |
|
# Generate a "Project" file, consisting of lines containing each of the |
# VHDL_SOURCES, preceded by "vhdl work". |
|
$(PROJ).prj : |
$(shell echo -n $(VHDL_SOURCES) | \ |
sed 's/\([^ ]\+\) */vhdl work \1\n/g' > $@) |
|
$(PROJ).xst-script : |
@echo "set -tmpdir /tmp" > $@ |
@echo "set -xsthdpdir ." >> $@ |
@echo "run" >> $@ |
@echo "-ifn $(PROJ).prj" >> $@ |
@echo "-ifmt mixed" >> $@ |
@echo "-ofn $(PROJ)" >> $@ |
@echo "-ofmt ngc" >> $@ |
@echo "-p $(FPGA_TYPE)" >> $@ |
@echo "-top $(TOPLEVEL)" >> $@ |
@echo "-opt_mode speed" >> $@ |
@echo "-opt_level 1" >> $@ |
@echo "-iuc no" >> $@ |
@echo "-lso $(PROJ).lso" >> $@ |
@echo "-keep_hierarchy no" >> $@ |
@echo "-glob_opt AllClockNets" >> $@ |
@echo "-rtlview no" >> $@ |
@echo "-read_cores yes" >> $@ |
# Note: write_timing_constraints is non-standard |
@echo "-write_timing_constraints yes" >> $@ |
@echo "-cross_clock_analysis no" >> $@ |
# @echo "-hierarchy_separator _" >> $@ |
@echo "-bus_delimiter <>" >> $@ |
@echo "-case maintain" >> $@ |
@echo "-slice_utilization_ratio 100" >> $@ |
# @echo "-verilog2001 yes" >> $@ |
# @echo "-vlgincdir" >> $@ |
@echo "-fsm_extract yes" >> $@ |
@echo "-fsm_encoding auto" >> $@ |
@echo "-fsm_style lut" >> $@ |
# Note: safe_implementation is non-standard |
@echo "-safe_implementation yes" >> $@ |
@echo "-ram_extract yes" >> $@ |
@echo "-ram_style auto" >> $@ |
@echo "-rom_extract yes" >> $@ |
@echo "-rom_style auto" >> $@ |
@echo "-mux_extract yes" >> $@ |
@echo "-mux_style auto" >> $@ |
@echo "-decoder_extract yes" >> $@ |
@echo "-priority_extract yes" >> $@ |
@echo "-shreg_extract yes" >> $@ |
@echo "-shift_extract yes" >> $@ |
@echo "-xor_collapse yes" >> $@ |
@echo "-resource_sharing yes" >> $@ |
@echo "-mult_style auto" >> $@ |
@echo "-iobuf yes" >> $@ |
@echo "-max_fanout 500" >> $@ |
@echo "-bufg 8" >> $@ |
@echo "-register_duplication yes" >> $@ |
@echo "-equivalent_register_removal yes" >> $@ |
@echo "-register_balancing no" >> $@ |
@echo "-slice_packing yes" >> $@ |
@echo "-optimize_primitives no" >> $@ |
@echo "-iob auto" >> $@ |
|
$(PROJ).ngc $(PROJ).xst.log : $(VHDL_SOURCES) $(PROJ).prj $(PROJ).lso $(PROJ).xst-script |
rm -rf work dump.xst |
xst $(OPT_INTSTYLE) -ifn $(PROJ).xst-script -ofn $(PROJ).xst.log |
rm -rf work dump.xst |
|
############################################################################### |
# # |
# STAGE 2: ngdbuild # |
# needs: # |
# # |
# $(PROJ).ngc # |
# # |
# created files: # |
# # |
# $(PROJ).bld - human-readable build log # |
# $(PROJ).ngd - XILINX-XDB 0.1 STUB 0.1 ASCII / XILINX-XDM V1.2e # |
# # |
# created dir: # |
# _ngo # |
# # |
############################################################################### |
|
$(PROJ).ngd $(PROJ).bld: $(PROJ).ngc $(UCFFILE) |
rm -rf _ngo |
ngdbuild $(OPT_INTSTYLE) -dd _ngo -aul -p $(FPGA_TYPE) $(if $(UCFFILE),-uc $(UCFFILE)) $(PROJ).ngc $(PROJ).ngd |
rm -rf _ngo |
|
############################################################################### |
# # |
# STAGE 3: Mapper # |
# needs: # |
# # |
# $(PROJ).ngd # |
# # |
# created files: # |
# # |
# $(PROJ).pcf - ASCII file # |
# $(PROJ)_map.mrp - human-readable mapping report # |
# $(PROJ)_map.ncd - binary format # |
# $(PROJ)_map.ngm - XILINX-XDB 0.1 STUB 0.1 ASCII / XILINX-XDM V1.2e # |
# # |
# NOTE: # |
# # |
# In order to prevent the make process from terminating on these spurious # |
# problems, we precede the "map" invocation with a hyphen, instructing # |
# make to ignore the return code from "map". # |
# # |
############################################################################### |
|
$(PROJ).pcf $(PROJ)_map.mrp $(PROJ)_map.ncd $(PROJ)_map.ngm: $(PROJ).ngd |
map $(OPT_INTSTYLE) -p $(FPGA_TYPE) -cm area -pr b -c 100 -o $(PROJ)_map.ncd $(PROJ).ngd $(PROJ).pcf |
|
############################################################################### |
# # |
# STAGE 4: Place-and-Route # |
# needs: # |
# # |
# $(PROJ).pcf # |
# $(PROJ)_map.ncd # |
# # |
# created files: # |
# # |
# $(PROJ).ncd - binary file # |
# $(PROJ).pad - ASCII file for import in spreadsheet # |
# $(PROJ).par - human-readable place-and-route report # |
# $(PROJ).xpi - ASCII file # |
# $(PROJ)_pad.csv - human-readable CVS file # |
# $(PROJ)_pad.txt - human-readable file # |
# # |
############################################################################### |
|
$(PROJ).ncd $(PROJ).pad $(PROJ).par $(PROJ).xpi $(PROJ)_pad.csv $(PROJ)_pad.txt: $(PROJ).pcf $(PROJ)_map.ncd |
par -w $(OPT_INTSTYLE) -t 1 $(PROJ)_map.ncd $(PROJ).ncd $(PROJ).pcf |
|
############################################################################### |
# # |
# STAGE 4.5 (optional): trace # |
# needs: # |
# # |
# created files: # |
# # |
############################################################################### |
|
$(PROJ).twr $(PROJ).twx : $(PROJ).ncd $(PROJ).pcf |
trce $(OPT_INTSTYLE) -e 5 -l 5 -u 5 -xml $(PROJ) $(PROJ).ncd -o $(PROJ).twr $(PROJ).pcf |
|
############################################################################### |
# # |
# STAGE 5: Generate BIT-file # |
# needs: # |
# # |
# $(PROJ).ncd # |
# # |
# created files: $(PROJ).bgn $(PROJ).bit $(PROJ).drc # |
# # |
# $(PROJ).bgn - human-readable BitGen report # |
# $(PROJ).drc - human readable DRC report # |
# $(PROJ).bit - binary image file # |
# # |
############################################################################### |
|
# We omit "-g StartUpClk:JtagClk" ; this doesn't work if the image is loaded |
# from a PROM. |
|
# Note: LCK_cycle:3 is non-standard |
OPT_BITGEN = -w \ |
-g DebugBitstream:No \ |
-g Binary:no \ |
-g CRC:Enable \ |
-g ConfigRate:6 \ |
-g CclkPin:PullUp \ |
-g M0Pin:PullUp \ |
-g M1Pin:PullUp \ |
-g M2Pin:PullUp \ |
-g ProgPin:PullUp \ |
-g DonePin:PullUp \ |
-g TckPin:PullUp \ |
-g TdiPin:PullUp \ |
-g TdoPin:PullUp \ |
-g TmsPin:PullUp \ |
-g UnusedPin:PullDown \ |
-g UserID:0xFFFFFFFF \ |
-g DCMShutDown:Disable \ |
-g DONE_cycle:4 \ |
-g GTS_cycle:5 \ |
-g GWE_cycle:6 \ |
-g LCK_cycle:3 \ |
-g Match_cycle:Auto \ |
-g Security:None \ |
-g DonePipe:No \ |
-g DriveDone:No |
|
$(PROJ).bit $(PROJ).bgn $(PROJ).drc: $(PROJ).ncd |
bitgen $(OPT_INTSTYLE) $(OPT_BITGEN) $(PROJ).ncd |
|
############################################################################### |
|
/LGPL-2.1.txt
0,0 → 1,510
|
GNU LESSER GENERAL PUBLIC LICENSE |
Version 2.1, February 1999 |
|
Copyright (C) 1991, 1999 Free Software Foundation, Inc. |
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
|
[This is the first released version of the Lesser GPL. It also counts |
as the successor of the GNU Library Public License, version 2, hence |
the version number 2.1.] |
|
Preamble |
|
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
Licenses are intended to guarantee your freedom to share and change |
free software--to make sure the software is free for all its users. |
|
This license, the Lesser General Public License, applies to some |
specially designated software packages--typically libraries--of the |
Free Software Foundation and other authors who decide to use it. You |
can use it too, but we suggest you first think carefully about whether |
this license or the ordinary General Public License is the better |
strategy to use in any particular case, based on the explanations |
below. |
|
When we speak of free software, we are referring to freedom of use, |
not price. Our General Public Licenses are designed to make sure that |
you have the freedom to distribute copies of free software (and charge |
for this service if you wish); that you receive source code or can get |
it if you want it; that you can change the software and use pieces of |
it in new free programs; and that you are informed that you can do |
these things. |
|
To protect your rights, we need to make restrictions that forbid |
distributors to deny you these rights or to ask you to surrender these |
rights. These restrictions translate to certain responsibilities for |
you if you distribute copies of the library or if you modify it. |
|
For example, if you distribute copies of the library, whether gratis |
or for a fee, you must give the recipients all the rights that we gave |
you. You must make sure that they, too, receive or can get the source |
code. If you link other code with the library, you must provide |
complete object files to the recipients, so that they can relink them |
with the library after making changes to the library and recompiling |
it. And you must show them these terms so they know their rights. |
|
We protect your rights with a two-step method: (1) we copyright the |
library, and (2) we offer you this license, which gives you legal |
permission to copy, distribute and/or modify the library. |
|
To protect each distributor, we want to make it very clear that |
there is no warranty for the free library. Also, if the library is |
modified by someone else and passed on, the recipients should know |
that what they have is not the original version, so that the original |
author's reputation will not be affected by problems that might be |
introduced by others. |
|
Finally, software patents pose a constant threat to the existence of |
any free program. We wish to make sure that a company cannot |
effectively restrict the users of a free program by obtaining a |
restrictive license from a patent holder. Therefore, we insist that |
any patent license obtained for a version of the library must be |
consistent with the full freedom of use specified in this license. |
|
Most GNU software, including some libraries, is covered by the |
ordinary GNU General Public License. This license, the GNU Lesser |
General Public License, applies to certain designated libraries, and |
is quite different from the ordinary General Public License. We use |
this license for certain libraries in order to permit linking those |
libraries into non-free programs. |
|
When a program is linked with a library, whether statically or using |
a shared library, the combination of the two is legally speaking a |
combined work, a derivative of the original library. The ordinary |
General Public License therefore permits such linking only if the |
entire combination fits its criteria of freedom. The Lesser General |
Public License permits more lax criteria for linking other code with |
the library. |
|
We call this license the "Lesser" General Public License because it |
does Less to protect the user's freedom than the ordinary General |
Public License. It also provides other free software developers Less |
of an advantage over competing non-free programs. These disadvantages |
are the reason we use the ordinary General Public License for many |
libraries. However, the Lesser license provides advantages in certain |
special circumstances. |
|
For example, on rare occasions, there may be a special need to |
encourage the widest possible use of a certain library, so that it |
becomes a de-facto standard. To achieve this, non-free programs must |
be allowed to use the library. A more frequent case is that a free |
library does the same job as widely used non-free libraries. In this |
case, there is little to gain by limiting the free library to free |
software only, so we use the Lesser General Public License. |
|
In other cases, permission to use a particular library in non-free |
programs enables a greater number of people to use a large body of |
free software. For example, permission to use the GNU C Library in |
non-free programs enables many more people to use the whole GNU |
operating system, as well as its variant, the GNU/Linux operating |
system. |
|
Although the Lesser General Public License is Less protective of the |
users' freedom, it does ensure that the user of a program that is |
linked with the Library has the freedom and the wherewithal to run |
that program using a modified version of the Library. |
|
The precise terms and conditions for copying, distribution and |
modification follow. Pay close attention to the difference between a |
"work based on the library" and a "work that uses the library". The |
former contains code derived from the library, whereas the latter must |
be combined with the library in order to run. |
|
GNU LESSER GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
|
0. This License Agreement applies to any software library or other |
program which contains a notice placed by the copyright holder or |
other authorized party saying it may be distributed under the terms of |
this Lesser General Public License (also called "this License"). |
Each licensee is addressed as "you". |
|
A "library" means a collection of software functions and/or data |
prepared so as to be conveniently linked with application programs |
(which use some of those functions and data) to form executables. |
|
The "Library", below, refers to any such software library or work |
which has been distributed under these terms. A "work based on the |
Library" means either the Library or any derivative work under |
copyright law: that is to say, a work containing the Library or a |
portion of it, either verbatim or with modifications and/or translated |
straightforwardly into another language. (Hereinafter, translation is |
included without limitation in the term "modification".) |
|
"Source code" for a work means the preferred form of the work for |
making modifications to it. For a library, complete source code means |
all the source code for all modules it contains, plus any associated |
interface definition files, plus the scripts used to control |
compilation and installation of the library. |
|
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running a program using the Library is not restricted, and output from |
such a program is covered only if its contents constitute a work based |
on the Library (independent of the use of the Library in a tool for |
writing it). Whether that is true depends on what the Library does |
and what the program that uses the Library does. |
|
1. You may copy and distribute verbatim copies of the Library's |
complete source code as you receive it, in any medium, provided that |
you conspicuously and appropriately publish on each copy an |
appropriate copyright notice and disclaimer of warranty; keep intact |
all the notices that refer to this License and to the absence of any |
warranty; and distribute a copy of this License along with the |
Library. |
|
You may charge a fee for the physical act of transferring a copy, |
and you may at your option offer warranty protection in exchange for a |
fee. |
|
2. You may modify your copy or copies of the Library or any portion |
of it, thus forming a work based on the Library, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
|
a) The modified work must itself be a software library. |
|
b) You must cause the files modified to carry prominent notices |
stating that you changed the files and the date of any change. |
|
c) You must cause the whole of the work to be licensed at no |
charge to all third parties under the terms of this License. |
|
d) If a facility in the modified Library refers to a function or a |
table of data to be supplied by an application program that uses |
the facility, other than as an argument passed when the facility |
is invoked, then you must make a good faith effort to ensure that, |
in the event an application does not supply such function or |
table, the facility still operates, and performs whatever part of |
its purpose remains meaningful. |
|
(For example, a function in a library to compute square roots has |
a purpose that is entirely well-defined independent of the |
application. Therefore, Subsection 2d requires that any |
application-supplied function or table used by this function must |
be optional: if the application does not supply it, the square |
root function must still compute square roots.) |
|
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Library, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Library, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote |
it. |
|
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Library. |
|
In addition, mere aggregation of another work not based on the Library |
with the Library (or with a work based on the Library) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
|
3. You may opt to apply the terms of the ordinary GNU General Public |
License instead of this License to a given copy of the Library. To do |
this, you must alter all the notices that refer to this License, so |
that they refer to the ordinary GNU General Public License, version 2, |
instead of to this License. (If a newer version than version 2 of the |
ordinary GNU General Public License has appeared, then you can specify |
that version instead if you wish.) Do not make any other change in |
these notices. |
|
Once this change is made in a given copy, it is irreversible for |
that copy, so the ordinary GNU General Public License applies to all |
subsequent copies and derivative works made from that copy. |
|
This option is useful when you wish to copy part of the code of |
the Library into a program that is not a library. |
|
4. You may copy and distribute the Library (or a portion or |
derivative of it, under Section 2) in object code or executable form |
under the terms of Sections 1 and 2 above provided that you accompany |
it with the complete corresponding machine-readable source code, which |
must be distributed under the terms of Sections 1 and 2 above on a |
medium customarily used for software interchange. |
|
If distribution of object code is made by offering access to copy |
from a designated place, then offering equivalent access to copy the |
source code from the same place satisfies the requirement to |
distribute the source code, even though third parties are not |
compelled to copy the source along with the object code. |
|
5. A program that contains no derivative of any portion of the |
Library, but is designed to work with the Library by being compiled or |
linked with it, is called a "work that uses the Library". Such a |
work, in isolation, is not a derivative work of the Library, and |
therefore falls outside the scope of this License. |
|
However, linking a "work that uses the Library" with the Library |
creates an executable that is a derivative of the Library (because it |
contains portions of the Library), rather than a "work that uses the |
library". The executable is therefore covered by this License. |
Section 6 states terms for distribution of such executables. |
|
When a "work that uses the Library" uses material from a header file |
that is part of the Library, the object code for the work may be a |
derivative work of the Library even though the source code is not. |
Whether this is true is especially significant if the work can be |
linked without the Library, or if the work is itself a library. The |
threshold for this to be true is not precisely defined by law. |
|
If such an object file uses only numerical parameters, data |
structure layouts and accessors, and small macros and small inline |
functions (ten lines or less in length), then the use of the object |
file is unrestricted, regardless of whether it is legally a derivative |
work. (Executables containing this object code plus portions of the |
Library will still fall under Section 6.) |
|
Otherwise, if the work is a derivative of the Library, you may |
distribute the object code for the work under the terms of Section 6. |
Any executables containing that work also fall under Section 6, |
whether or not they are linked directly with the Library itself. |
|
6. As an exception to the Sections above, you may also combine or |
link a "work that uses the Library" with the Library to produce a |
work containing portions of the Library, and distribute that work |
under terms of your choice, provided that the terms permit |
modification of the work for the customer's own use and reverse |
engineering for debugging such modifications. |
|
You must give prominent notice with each copy of the work that the |
Library is used in it and that the Library and its use are covered by |
this License. You must supply a copy of this License. If the work |
during execution displays copyright notices, you must include the |
copyright notice for the Library among them, as well as a reference |
directing the user to the copy of this License. Also, you must do one |
of these things: |
|
a) Accompany the work with the complete corresponding |
machine-readable source code for the Library including whatever |
changes were used in the work (which must be distributed under |
Sections 1 and 2 above); and, if the work is an executable linked |
with the Library, with the complete machine-readable "work that |
uses the Library", as object code and/or source code, so that the |
user can modify the Library and then relink to produce a modified |
executable containing the modified Library. (It is understood |
that the user who changes the contents of definitions files in the |
Library will not necessarily be able to recompile the application |
to use the modified definitions.) |
|
b) Use a suitable shared library mechanism for linking with the |
Library. A suitable mechanism is one that (1) uses at run time a |
copy of the library already present on the user's computer system, |
rather than copying library functions into the executable, and (2) |
will operate properly with a modified version of the library, if |
the user installs one, as long as the modified version is |
interface-compatible with the version that the work was made with. |
|
c) Accompany the work with a written offer, valid for at least |
three years, to give the same user the materials specified in |
Subsection 6a, above, for a charge no more than the cost of |
performing this distribution. |
|
d) If distribution of the work is made by offering access to copy |
from a designated place, offer equivalent access to copy the above |
specified materials from the same place. |
|
e) Verify that the user has already received a copy of these |
materials or that you have already sent this user a copy. |
|
For an executable, the required form of the "work that uses the |
Library" must include any data and utility programs needed for |
reproducing the executable from it. However, as a special exception, |
the materials to be distributed need not include anything that is |
normally distributed (in either source or binary form) with the major |
components (compiler, kernel, and so on) of the operating system on |
which the executable runs, unless that component itself accompanies |
the executable. |
|
It may happen that this requirement contradicts the license |
restrictions of other proprietary libraries that do not normally |
accompany the operating system. Such a contradiction means you cannot |
use both them and the Library together in an executable that you |
distribute. |
|
7. You may place library facilities that are a work based on the |
Library side-by-side in a single library together with other library |
facilities not covered by this License, and distribute such a combined |
library, provided that the separate distribution of the work based on |
the Library and of the other library facilities is otherwise |
permitted, and provided that you do these two things: |
|
a) Accompany the combined library with a copy of the same work |
based on the Library, uncombined with any other library |
facilities. This must be distributed under the terms of the |
Sections above. |
|
b) Give prominent notice with the combined library of the fact |
that part of it is a work based on the Library, and explaining |
where to find the accompanying uncombined form of the same work. |
|
8. You may not copy, modify, sublicense, link with, or distribute |
the Library except as expressly provided under this License. Any |
attempt otherwise to copy, modify, sublicense, link with, or |
distribute the Library is void, and will automatically terminate your |
rights under this License. However, parties who have received copies, |
or rights, from you under this License will not have their licenses |
terminated so long as such parties remain in full compliance. |
|
9. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Library or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Library (or any work based on the |
Library), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Library or works based on it. |
|
10. Each time you redistribute the Library (or any work based on the |
Library), the recipient automatically receives a license from the |
original licensor to copy, distribute, link with or modify the Library |
subject to these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties with |
this License. |
|
11. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Library at all. For example, if a patent |
license would not permit royalty-free redistribution of the Library by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Library. |
|
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply, and the section as a whole is intended to apply in other |
circumstances. |
|
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
|
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
|
12. If the distribution and/or use of the Library is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Library under this License |
may add an explicit geographical distribution limitation excluding those |
countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
|
13. The Free Software Foundation may publish revised and/or new |
versions of the Lesser General Public License from time to time. |
Such new versions will be similar in spirit to the present version, |
but may differ in detail to address new problems or concerns. |
|
Each version is given a distinguishing version number. If the Library |
specifies a version number of this License which applies to it and |
"any later version", you have the option of following the terms and |
conditions either of that version or of any later version published by |
the Free Software Foundation. If the Library does not specify a |
license version number, you may choose any version ever published by |
the Free Software Foundation. |
|
14. If you wish to incorporate parts of the Library into other free |
programs whose distribution conditions are incompatible with these, |
write to the author to ask for permission. For software which is |
copyrighted by the Free Software Foundation, write to the Free |
Software Foundation; we sometimes make exceptions for this. Our |
decision will be guided by the two goals of preserving the free status |
of all derivatives of our free software and of promoting the sharing |
and reuse of software generally. |
|
NO WARRANTY |
|
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO |
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. |
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR |
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY |
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE |
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME |
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |
|
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN |
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY |
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU |
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE |
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING |
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A |
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF |
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
DAMAGES. |
|
END OF TERMS AND CONDITIONS |
|
How to Apply These Terms to Your New Libraries |
|
If you develop a new library, and you want it to be of the greatest |
possible use to the public, we recommend making it free software that |
everyone can redistribute and change. You can do so by permitting |
redistribution under these terms (or, alternatively, under the terms |
of the ordinary General Public License). |
|
To apply these terms, attach the following notices to the library. |
It is safest to attach them to the start of each source file to most |
effectively convey the exclusion of warranty; and each file should |
have at least the "copyright" line and a pointer to where the full |
notice is found. |
|
|
<one line to give the library's name and a brief idea of what it does.> |
Copyright (C) <year> <name of author> |
|
This library is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public |
License as published by the Free Software Foundation; either |
version 2.1 of the License, or (at your option) any later version. |
|
This library is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with this library; if not, write to the Free Software |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
|
Also add information on how to contact you by electronic and paper mail. |
|
You should also get your employer (if you work as a programmer) or |
your school, if any, to sign a "copyright disclaimer" for the library, |
if necessary. Here is a sample; alter the names: |
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the |
library `Frob' (a library for tweaking knobs) written by James |
Random Hacker. |
|
<signature of Ty Coon>, 1 April 1990 |
Ty Coon, President of Vice |
|
That's all there is to it! |
|
|
/README.txt
0,0 → 1,62
|
SpaceWire Light |
=============== |
|
Copyright 2009-2010 Joris van Rantwijk |
|
SpaceWire Light is free software; you can redistribute it and/or |
modify it under the terms of the GNU Lesser General Public License |
as published by the Free Software Foundation; either version 2.1 |
of the License, or (at your option) any later version. |
|
SpaceWire Light is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU Lesser General Public License for more details. |
|
You should have received a copy of the GNU Lesser General Public |
License along with the SpaceWire Light package. If not, see |
<http://www.gnu.org/licenses/>. |
|
|
Overview |
-------- |
|
SpaceWire Light is a SpaceWire encoder-decoder with FIFO interface. |
It is synthesizable for FPGA targets (up to 200 Mbit on Spartan-3). |
|
The goal is to provide a complete, reliable, fast implementation |
of a SpaceWire encoder-decoder according to ECSS-E-50-12C. |
The core is "light" in the sense that it does not provide additional |
features such as RMAP, routing etc. |
|
This core would be very suitable for application in lab environments, |
to add a SpaceWire interface to a custom FPGA design, and for interfacing |
between existing SpaceWire equipment and a computer. |
|
The project is currently very much in alpha phase. Most importantly, |
there is no proper documentation. I WILL PROVIDE DOCUMENTATION SOON. |
|
Short term plan: |
* more testing |
* documentation |
|
Long term plan: |
* add AMBA bus interface |
|
|
Contact |
------- |
|
For the latest version of this core, see the OpenCores project page. |
|
For more information, comments, suggestions or bug reports, either |
go to the OpenCores project page or email me directly. |
|
Project page at OpenCores: |
http://opencores.org/project,spacewire_light |
|
Email: |
jvrantwijk (at) xs4all (dot) nl |
|
-- |