init. Works on altera
This commit is contained in:
commit
4f4c36ffe8
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
*~
|
||||||
|
*.bak
|
||||||
|
*.ghw
|
||||||
|
*.o
|
||||||
|
temp
|
118
bench/test.vhd
Normal file
118
bench/test.vhd
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
entity test is
|
||||||
|
|
||||||
|
end entity test;
|
||||||
|
|
||||||
|
architecture bench of test is
|
||||||
|
|
||||||
|
signal clk : std_logic;
|
||||||
|
signal rst : std_logic := '1';
|
||||||
|
signal dv : std_logic;
|
||||||
|
signal rx : std_logic_vector(1 downto 0);
|
||||||
|
signal mdc : std_logic;
|
||||||
|
signal mdio : std_logic;
|
||||||
|
signal led : std_logic_vector(1 downto 0);
|
||||||
|
signal ws : std_logic;
|
||||||
|
begin -- architecture bench
|
||||||
|
|
||||||
|
|
||||||
|
top_1 : entity work.top
|
||||||
|
port map (
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
mdio => mdio,
|
||||||
|
mdc => mdc,
|
||||||
|
rx => rx,
|
||||||
|
dv => dv,
|
||||||
|
led1 => led(0),
|
||||||
|
led2 => led(1),
|
||||||
|
ws_out => ws);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
clkgen : process is
|
||||||
|
begin
|
||||||
|
clk <= '0';
|
||||||
|
wait for 10 ns;
|
||||||
|
clk <= '1';
|
||||||
|
wait for 10 ns;
|
||||||
|
end process clkgen;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sendphy : process is
|
||||||
|
procedure sendRMII(byte : in std_logic_vector(7 downto 0)) is
|
||||||
|
begin
|
||||||
|
wait until falling_edge(clk);
|
||||||
|
dv <= '1';
|
||||||
|
rx <= byte(1 downto 0);
|
||||||
|
wait until falling_edge(clk);
|
||||||
|
rx <= byte(3 downto 2);
|
||||||
|
wait until falling_edge(clk);
|
||||||
|
rx <= byte(5 downto 4);
|
||||||
|
wait until falling_edge(clk);
|
||||||
|
rx <= byte(7 downto 6);
|
||||||
|
|
||||||
|
end procedure sendRMII;
|
||||||
|
begin
|
||||||
|
dv <= '0';
|
||||||
|
|
||||||
|
wait for 35 ns;
|
||||||
|
rst <= '0';
|
||||||
|
dv <= '0';
|
||||||
|
rx <= "00";
|
||||||
|
wait for 100 us;
|
||||||
|
sendRMII(x"55");
|
||||||
|
sendRMII(x"55");
|
||||||
|
sendRMII(x"55");
|
||||||
|
sendRMII(x"55");
|
||||||
|
sendRMII(x"55");
|
||||||
|
sendRMII(x"55");
|
||||||
|
sendRMII(x"55");
|
||||||
|
sendRMII(x"55");
|
||||||
|
sendRMII(x"D5");
|
||||||
|
|
||||||
|
sendRMII(x"00");
|
||||||
|
sendRMII(x"DE");
|
||||||
|
sendRMII(x"AD");
|
||||||
|
sendRMII(x"BE");
|
||||||
|
sendRMII(x"EF");
|
||||||
|
sendRMII(x"00");
|
||||||
|
|
||||||
|
sendRMII(x"01");
|
||||||
|
sendRMII(x"02");
|
||||||
|
sendRMII(x"03");
|
||||||
|
sendRMII(x"04");
|
||||||
|
sendRMII(x"05");
|
||||||
|
sendRMII(x"06");
|
||||||
|
|
||||||
|
sendRMII(x"01");
|
||||||
|
sendRMII(x"02");
|
||||||
|
|
||||||
|
sendRMII(x"AA");
|
||||||
|
|
||||||
|
sendRMII(x"01");
|
||||||
|
sendRMII(x"02");
|
||||||
|
|
||||||
|
|
||||||
|
sendRMII(x"CC");
|
||||||
|
sendRMII(x"AA");
|
||||||
|
sendRMII(x"55");
|
||||||
|
-- Send FCS
|
||||||
|
sendRMII(x"BD");
|
||||||
|
sendRMII(x"9B");
|
||||||
|
sendRMII(x"AC");
|
||||||
|
sendRMII(x"54");
|
||||||
|
|
||||||
|
-- sendRMII(x"AB");
|
||||||
|
|
||||||
|
wait until falling_edge(clk);
|
||||||
|
wait for 10 ns;
|
||||||
|
dv <= '0';
|
||||||
|
wait;
|
||||||
|
end process sendphy;
|
||||||
|
end architecture bench;
|
195
eth/ehtmac_rx.vhd
Normal file
195
eth/ehtmac_rx.vhd
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Title : Ethernet RX Core
|
||||||
|
-- Project : EthMAC
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- File : design/ethmac_rx.vhd
|
||||||
|
-- Author : Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
-- Standard : VHDL'93/02
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Description: LED Demonstration for Ethernet RX + TX
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Copyright (c) 2016
|
||||||
|
--
|
||||||
|
-- This file is part of EthMAC.
|
||||||
|
--
|
||||||
|
-- EthMAC 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, version 2 of the License.
|
||||||
|
--
|
||||||
|
-- This code 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 code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity ethmac_rx is
|
||||||
|
port(
|
||||||
|
clk_50 : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
rmii_rx : in std_logic_vector(1 downto 0);
|
||||||
|
rmii_dv : in std_logic;
|
||||||
|
start_of_frame : out std_logic;
|
||||||
|
end_of_frame : out std_logic;
|
||||||
|
data_out : out std_logic_vector(7 downto 0);
|
||||||
|
data_strb : out std_logic;
|
||||||
|
crc_check_valid : out std_logic
|
||||||
|
);
|
||||||
|
end entity ethmac_rx;
|
||||||
|
|
||||||
|
architecture RTL of ethmac_rx is
|
||||||
|
type ethstate_t is (ETH_INIT, ETH_PREAMBLE, ETH_DATA);
|
||||||
|
signal framestate : ethstate_t;
|
||||||
|
signal crc_data_in : std_logic_vector(7 downto 0);
|
||||||
|
signal crc_init : std_logic;
|
||||||
|
signal crc_calc_en : std_logic;
|
||||||
|
signal crc_data_valid : std_logic;
|
||||||
|
signal crc_valid : std_logic;
|
||||||
|
signal dibit_counter : integer range 0 to 3 := 0;
|
||||||
|
signal data_delay_in : std_logic_vector(7 downto 0);
|
||||||
|
signal data_delay_in_strb : std_logic;
|
||||||
|
signal data_delay_truncate : std_logic;
|
||||||
|
signal end_of_frame_s : std_logic;
|
||||||
|
type data_fifo_t is array (0 to 3) of std_logic_vector(7 downto 0);
|
||||||
|
|
||||||
|
signal data_delay_fifo : data_fifo_t;
|
||||||
|
|
||||||
|
-- signal datatype_reg: ethfield_t;
|
||||||
|
-- signal data : std_logic_vector( 7 downto 0);
|
||||||
|
begin
|
||||||
|
ethfcs_inst : entity work.ethfcs
|
||||||
|
port map(
|
||||||
|
CLOCK => clk_50,
|
||||||
|
RESET => rst,
|
||||||
|
DATA => crc_data_in,
|
||||||
|
LOAD_INIT => crc_init,
|
||||||
|
CALC => crc_calc_en,
|
||||||
|
D_VALID => crc_data_valid,
|
||||||
|
CRC => open,
|
||||||
|
CRC_REG => open,
|
||||||
|
CRC_VALID => crc_valid);
|
||||||
|
|
||||||
|
rx_framefsm : process(clk_50, rst) is
|
||||||
|
variable recv_byte : std_logic_vector(7 downto 0) := (others => '0');
|
||||||
|
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
framestate <= ETH_INIT;
|
||||||
|
dibit_counter <= 0;
|
||||||
|
recv_byte := (others => '0');
|
||||||
|
crc_calc_en <= '0';
|
||||||
|
data_delay_truncate <= '0';
|
||||||
|
data_delay_in_strb <= '0';
|
||||||
|
data_delay_in <= (others => '0');
|
||||||
|
crc_init <= '0';
|
||||||
|
crc_data_in <= (others => '0');
|
||||||
|
crc_data_valid <= '0';
|
||||||
|
crc_calc_en <= '0';
|
||||||
|
start_of_frame <= '0';
|
||||||
|
end_of_frame_s <= '0';
|
||||||
|
elsif rising_edge(clk_50) then
|
||||||
|
end_of_frame_s <= '0';
|
||||||
|
crc_calc_en <= '0';
|
||||||
|
start_of_frame <= '0';
|
||||||
|
data_delay_truncate <= '0';
|
||||||
|
data_delay_in_strb <= '0';
|
||||||
|
crc_init <= '0';
|
||||||
|
crc_data_valid <= '0';
|
||||||
|
if dibit_counter = 3 then
|
||||||
|
dibit_counter <= 0;
|
||||||
|
else
|
||||||
|
dibit_counter <= dibit_counter + 1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- input data shift register (LSB first)
|
||||||
|
recv_byte := rmii_rx & recv_byte(7 downto 2);
|
||||||
|
|
||||||
|
case framestate is
|
||||||
|
when ETH_INIT =>
|
||||||
|
if rmii_dv = '0' then -- Wait for inter frame gap for sync
|
||||||
|
crc_init <= '1';
|
||||||
|
framestate <= ETH_PREAMBLE;
|
||||||
|
end if;
|
||||||
|
when ETH_PREAMBLE =>
|
||||||
|
if rmii_dv = '1' and rmii_rx = "11" then -- Data valid and last dibit of preamble recieved
|
||||||
|
-- reset dibit counter
|
||||||
|
dibit_counter <= 0;
|
||||||
|
start_of_frame <= '1';
|
||||||
|
framestate <= ETH_DATA;
|
||||||
|
-- crc_init <= '1';
|
||||||
|
end if;
|
||||||
|
when ETH_DATA =>
|
||||||
|
crc_calc_en <= '1';
|
||||||
|
if rmii_dv = '1' then
|
||||||
|
if dibit_counter = 3 then -- Data word received
|
||||||
|
data_delay_in <= recv_byte;
|
||||||
|
data_delay_in_strb <= '1';
|
||||||
|
crc_data_in <= recv_byte;
|
||||||
|
crc_data_valid <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
framestate <= ETH_INIT;
|
||||||
|
end_of_frame_s <= '1';
|
||||||
|
crc_calc_en <= '0';
|
||||||
|
data_delay_truncate <= '1';
|
||||||
|
end if;
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end if;
|
||||||
|
end process rx_framefsm;
|
||||||
|
|
||||||
|
data_delay : process(rst, clk_50) is -- This implements a four byte big delay buffer/FIFO used for removing the crc
|
||||||
|
variable data_count : integer range 0 to 4 := 0;
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
data_out <= (others => '0');
|
||||||
|
data_strb <= '0';
|
||||||
|
data_count := 0;
|
||||||
|
for i in 0 to 3 loop
|
||||||
|
data_delay_fifo(i) <= (others => '0');
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
elsif rising_edge(clk_50) then
|
||||||
|
data_strb <= '0';
|
||||||
|
if data_delay_truncate = '1' then
|
||||||
|
data_count := 0; -- resetting counter is enough. FIFO itself has not to be cleared
|
||||||
|
elsif data_delay_in_strb = '1' then
|
||||||
|
data_delay_fifo(0) <= data_delay_in;
|
||||||
|
for i in 3 downto 1 loop
|
||||||
|
data_delay_fifo(i) <= data_delay_fifo(i - 1);
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
if data_count < 4 then
|
||||||
|
data_count := data_count + 1;
|
||||||
|
else -- Enable output
|
||||||
|
data_out <= data_delay_fifo(3);
|
||||||
|
data_strb <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process data_delay;
|
||||||
|
|
||||||
|
crc_valid_gen : process(crc_valid) is
|
||||||
|
begin
|
||||||
|
crc_check_valid <= crc_valid;
|
||||||
|
end process crc_valid_gen;
|
||||||
|
|
||||||
|
eof_sync : process(clk_50, rst) is
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
end_of_frame <= '0';
|
||||||
|
elsif rising_edge(clk_50) then
|
||||||
|
end_of_frame <= end_of_frame_s;
|
||||||
|
end if;
|
||||||
|
end process eof_sync;
|
||||||
|
|
||||||
|
end architecture RTL;
|
217
eth/eth-fcs.vhd
Normal file
217
eth/eth-fcs.vhd
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- CRC GENERATOR
|
||||||
|
-- Computes the CRC32 (802.3) for the input byte stream. Assert D_VALID to load
|
||||||
|
-- each byte for calculation. LOAD_INIT should be asserted at the beginning of a
|
||||||
|
-- data stream in order to prime with CRC generator with 32'hFFFFFFFF
|
||||||
|
-- which will cause the initial 32 bits in to be complemented as per 802.3.
|
||||||
|
--
|
||||||
|
-- IO DESCRIPTION
|
||||||
|
-- Clock: 100MHz Clock
|
||||||
|
-- Reset: Active high reset
|
||||||
|
-- Data: 8Bit Data In
|
||||||
|
-- Load Init: Asserted for one clock period, loads the CRC gen with 32'hFFFFFFFF
|
||||||
|
-- Calc: Asserted to enable calculation of the CRC.
|
||||||
|
-- D_valid: Asserted for one clock period, loads in the next byte on DATA.
|
||||||
|
--
|
||||||
|
-- @author Peter A Bennett
|
||||||
|
-- @copyright (c) 2012 Peter A Bennett
|
||||||
|
-- @version $Rev: 2 $
|
||||||
|
-- @lastrevision $Date: 2012-03-11 15:19:25 +0000 (Sun, 11 Mar 2012) $
|
||||||
|
-- @license LGPL
|
||||||
|
-- @email pab850@googlemail.com
|
||||||
|
-- @contact www.bytebash.com
|
||||||
|
--
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity ethfcs is
|
||||||
|
Port ( CLOCK : in std_logic;
|
||||||
|
RESET : in std_logic;
|
||||||
|
DATA : in std_logic_vector(7 downto 0);
|
||||||
|
LOAD_INIT : in std_logic;
|
||||||
|
CALC : in std_logic;
|
||||||
|
D_VALID : in std_logic;
|
||||||
|
CRC : out std_logic_vector(7 downto 0);
|
||||||
|
CRC_REG : out std_logic_vector(31 downto 0);
|
||||||
|
CRC_VALID : out std_logic
|
||||||
|
);
|
||||||
|
end ethfcs;
|
||||||
|
|
||||||
|
architecture RTL of ethfcs is
|
||||||
|
-- Block Diagram for Parallel CRC-32 generation.
|
||||||
|
-- (Based on Xilinx CRC App Note)
|
||||||
|
-- http://www.xilinx.com/support/documentation/application_notes/xapp209.pdf
|
||||||
|
-- Data In is byte reversed internally as per the requirements of the easics comb CRC block.
|
||||||
|
|
||||||
|
--
|
||||||
|
-- The "8-bit CRC Out" register always contains the bit-reversed and complimented most
|
||||||
|
-- significant bits of the "32-bit CRC" register. The final IEEE 802.3 FCS can be read from the
|
||||||
|
-- "8-bit CRC Out" register by asserting d_valid four times after the de-assertion of calc
|
||||||
|
--
|
||||||
|
-- +--------------------------------------+-----------------------------------+
|
||||||
|
-- | | _____ |
|
||||||
|
-- | comb_crc_gen next_crc(23:0) | | \ +--->CRC_REG(31:0)
|
||||||
|
-- | +---------------+ & x"FF" +-->|00 \ +-----+ |
|
||||||
|
-- +-->| Combinatorial |--------------------->|01 \__________|D Q|______|
|
||||||
|
--D(7:0) >--->| Next CRC Gen | xFFFFFFFF---->|10 / +--|---|En |
|
||||||
|
-- +---------------+ xFFFFFFFF---->|11 / | | +-----+ ____ +-----+
|
||||||
|
-- (complements first |_____/ | +------------>| = |-->|D Q|--> VALID_REG
|
||||||
|
-- 32 bits of frame) | | | residue ---->|____| +-|En |
|
||||||
|
--load_init >----------------------+------------------+ | | xC704DD7B | +-----+
|
||||||
|
--calc >-----------+ | | | |
|
||||||
|
--d_valid >-------+ | _ | | |-----------------------+
|
||||||
|
-- | +---|x\____|____________________| |
|
||||||
|
-- +---|---|_/ | _ |
|
||||||
|
-- | | +---|+\_______________________|
|
||||||
|
-- +---|----------+---|_/
|
||||||
|
-- | |
|
||||||
|
-- | +------------------------------------+
|
||||||
|
-- | ________ ____ | +-----+
|
||||||
|
-- | crc_reg (16:23)>-----|0 \ +--|En |
|
||||||
|
-- | ________ | \___|D Q|------>CRC(7:0)
|
||||||
|
-- | next_crc(24:31)>-----|1 / +-----+
|
||||||
|
-- | |_____/
|
||||||
|
-- | |
|
||||||
|
-- +------------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
-- First, the data stream and CRC of the received frame are sent through the circuit.
|
||||||
|
-- Then the value left in the CRC-32 registers can be compared with a constant, commonly
|
||||||
|
-- referred to as the residue. In this implementation, the value of the residue is 0xC704DD7B
|
||||||
|
-- when no CRC errors are detected. (Xilinx CRC App Note).
|
||||||
|
|
||||||
|
-- CRC32 (Easics generator).
|
||||||
|
function comb_crc_gen
|
||||||
|
(
|
||||||
|
data_in : std_logic_vector(7 downto 0);
|
||||||
|
crc_in : std_logic_vector(31 downto 0)
|
||||||
|
)
|
||||||
|
return std_logic_vector is
|
||||||
|
|
||||||
|
variable d: std_logic_vector(7 downto 0);
|
||||||
|
variable c: std_logic_vector(31 downto 0);
|
||||||
|
variable newcrc: std_logic_vector(31 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
d := data_in;
|
||||||
|
c := crc_in;
|
||||||
|
-- Easics
|
||||||
|
newcrc(0) := d(6) xor d(0) xor c(24) xor c(30);
|
||||||
|
newcrc(1) := d(7) xor d(6) xor d(1) xor d(0) xor c(24) xor c(25) xor c(30) xor c(31);
|
||||||
|
newcrc(2) := d(7) xor d(6) xor d(2) xor d(1) xor d(0) xor c(24) xor c(25) xor c(26) xor c(30) xor c(31);
|
||||||
|
newcrc(3) := d(7) xor d(3) xor d(2) xor d(1) xor c(25) xor c(26) xor c(27) xor c(31);
|
||||||
|
newcrc(4) := d(6) xor d(4) xor d(3) xor d(2) xor d(0) xor c(24) xor c(26) xor c(27) xor c(28) xor c(30);
|
||||||
|
newcrc(5) := d(7) xor d(6) xor d(5) xor d(4) xor d(3) xor d(1) xor d(0) xor c(24) xor c(25) xor c(27) xor c(28) xor c(29) xor c(30) xor c(31);
|
||||||
|
newcrc(6) := d(7) xor d(6) xor d(5) xor d(4) xor d(2) xor d(1) xor c(25) xor c(26) xor c(28) xor c(29) xor c(30) xor c(31);
|
||||||
|
newcrc(7) := d(7) xor d(5) xor d(3) xor d(2) xor d(0) xor c(24) xor c(26) xor c(27) xor c(29) xor c(31);
|
||||||
|
newcrc(8) := d(4) xor d(3) xor d(1) xor d(0) xor c(0) xor c(24) xor c(25) xor c(27) xor c(28);
|
||||||
|
newcrc(9) := d(5) xor d(4) xor d(2) xor d(1) xor c(1) xor c(25) xor c(26) xor c(28) xor c(29);
|
||||||
|
newcrc(10) := d(5) xor d(3) xor d(2) xor d(0) xor c(2) xor c(24) xor c(26) xor c(27) xor c(29);
|
||||||
|
newcrc(11) := d(4) xor d(3) xor d(1) xor d(0) xor c(3) xor c(24) xor c(25) xor c(27) xor c(28);
|
||||||
|
newcrc(12) := d(6) xor d(5) xor d(4) xor d(2) xor d(1) xor d(0) xor c(4) xor c(24) xor c(25) xor c(26) xor c(28) xor c(29) xor c(30);
|
||||||
|
newcrc(13) := d(7) xor d(6) xor d(5) xor d(3) xor d(2) xor d(1) xor c(5) xor c(25) xor c(26) xor c(27) xor c(29) xor c(30) xor c(31);
|
||||||
|
newcrc(14) := d(7) xor d(6) xor d(4) xor d(3) xor d(2) xor c(6) xor c(26) xor c(27) xor c(28) xor c(30) xor c(31);
|
||||||
|
newcrc(15) := d(7) xor d(5) xor d(4) xor d(3) xor c(7) xor c(27) xor c(28) xor c(29) xor c(31);
|
||||||
|
newcrc(16) := d(5) xor d(4) xor d(0) xor c(8) xor c(24) xor c(28) xor c(29);
|
||||||
|
newcrc(17) := d(6) xor d(5) xor d(1) xor c(9) xor c(25) xor c(29) xor c(30);
|
||||||
|
newcrc(18) := d(7) xor d(6) xor d(2) xor c(10) xor c(26) xor c(30) xor c(31);
|
||||||
|
newcrc(19) := d(7) xor d(3) xor c(11) xor c(27) xor c(31);
|
||||||
|
newcrc(20) := d(4) xor c(12) xor c(28);
|
||||||
|
newcrc(21) := d(5) xor c(13) xor c(29);
|
||||||
|
newcrc(22) := d(0) xor c(14) xor c(24);
|
||||||
|
newcrc(23) := d(6) xor d(1) xor d(0) xor c(15) xor c(24) xor c(25) xor c(30);
|
||||||
|
newcrc(24) := d(7) xor d(2) xor d(1) xor c(16) xor c(25) xor c(26) xor c(31);
|
||||||
|
newcrc(25) := d(3) xor d(2) xor c(17) xor c(26) xor c(27);
|
||||||
|
newcrc(26) := d(6) xor d(4) xor d(3) xor d(0) xor c(18) xor c(24) xor c(27) xor c(28) xor c(30);
|
||||||
|
newcrc(27) := d(7) xor d(5) xor d(4) xor d(1) xor c(19) xor c(25) xor c(28) xor c(29) xor c(31);
|
||||||
|
newcrc(28) := d(6) xor d(5) xor d(2) xor c(20) xor c(26) xor c(29) xor c(30);
|
||||||
|
newcrc(29) := d(7) xor d(6) xor d(3) xor c(21) xor c(27) xor c(30) xor c(31);
|
||||||
|
newcrc(30) := d(7) xor d(4) xor c(22) xor c(28) xor c(31);
|
||||||
|
newcrc(31) := d(5) xor c(23) xor c(29);
|
||||||
|
return newcrc;
|
||||||
|
end comb_crc_gen;
|
||||||
|
|
||||||
|
-- Reverse the input vector.
|
||||||
|
function reversed(slv: std_logic_vector) return std_logic_vector is
|
||||||
|
variable result: std_logic_vector(slv'reverse_range);
|
||||||
|
begin
|
||||||
|
for i in slv'range loop
|
||||||
|
result(i) := slv(i);
|
||||||
|
end loop;
|
||||||
|
return result;
|
||||||
|
end reversed;
|
||||||
|
|
||||||
|
|
||||||
|
-- Magic number for the CRC generator.
|
||||||
|
constant c_crc_residue : std_logic_vector(31 downto 0) := x"C704DD7B";
|
||||||
|
signal s_next_crc : std_logic_vector(31 downto 0) := (others => '0');
|
||||||
|
signal s_crc_reg : std_logic_vector(31 downto 0) := (others => '0');
|
||||||
|
signal s_crc : std_logic_vector(7 downto 0) := (others => '0');
|
||||||
|
signal s_reversed_byte : std_logic_vector(7 downto 0) := (others => '0');
|
||||||
|
signal s_crc_valid : std_logic := '0';
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
CRC <= s_crc;
|
||||||
|
CRC_REG <= s_crc_reg;
|
||||||
|
CRC_VALID <= s_crc_valid;
|
||||||
|
|
||||||
|
BYTE_REVERSE : process (DATA)
|
||||||
|
-- Nibble swapped and Bit reversed version of DATA
|
||||||
|
begin
|
||||||
|
--s_reversed_byte <= reversed(DATA(3 downto 0) & DATA(7 downto 4));
|
||||||
|
s_reversed_byte <= reversed(DATA);
|
||||||
|
end process;
|
||||||
|
|
||||||
|
COMB_NEXT_CRC_GEN : process (s_reversed_byte, s_crc_reg)
|
||||||
|
begin
|
||||||
|
s_next_crc <= comb_crc_gen(s_reversed_byte, s_crc_reg);
|
||||||
|
end process COMB_NEXT_CRC_GEN;
|
||||||
|
|
||||||
|
CRC_GEN : process (CLOCK)
|
||||||
|
variable state : std_logic_vector(2 downto 0);
|
||||||
|
begin
|
||||||
|
if rising_edge(CLOCK) then
|
||||||
|
if RESET = '1' then
|
||||||
|
s_crc_reg <= (others => '0');
|
||||||
|
s_crc <= (others => '0');
|
||||||
|
s_crc_valid <= '0';
|
||||||
|
state := (others => '0');
|
||||||
|
else
|
||||||
|
state := LOAD_INIT & CALC & D_VALID;
|
||||||
|
case state is
|
||||||
|
when "000" =>
|
||||||
|
-- No change.
|
||||||
|
when "001" =>
|
||||||
|
s_crc_reg <= s_crc_reg(23 downto 0) & x"FF";
|
||||||
|
s_crc <= not reversed(s_crc_reg(23 downto 16));
|
||||||
|
when "010" =>
|
||||||
|
-- No Change
|
||||||
|
when "011" =>
|
||||||
|
s_crc_reg <= s_next_crc;
|
||||||
|
s_crc <= not reversed(s_next_crc(31 downto 24));
|
||||||
|
when "100" =>
|
||||||
|
s_crc_reg <= x"FFFFFFFF";
|
||||||
|
when "101" =>
|
||||||
|
s_crc_reg <= x"FFFFFFFF";
|
||||||
|
s_crc <= not reversed(s_crc_reg(23 downto 16));
|
||||||
|
when "110" =>
|
||||||
|
s_crc_reg <= x"FFFFFFFF";
|
||||||
|
when "111" =>
|
||||||
|
s_crc_reg <= x"FFFFFFFF";
|
||||||
|
s_crc <= not reversed(s_next_crc(31 downto 24));
|
||||||
|
when others =>
|
||||||
|
null;
|
||||||
|
end case;
|
||||||
|
if c_crc_residue = s_crc_reg then
|
||||||
|
s_crc_valid <= '1';
|
||||||
|
else
|
||||||
|
s_crc_valid <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process CRC_GEN;
|
||||||
|
end RTL;
|
193
eth/smi.vhd
Normal file
193
eth/smi.vhd
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Title : SMI (MDIO)
|
||||||
|
-- Project : EthMAC
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- File : design/smi.vhd
|
||||||
|
-- Author : Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
-- Standard : VHDL'93/02
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Description: SMI/MDIO Implementation for Ethernet PHYs
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Copyright (c) 2016
|
||||||
|
--
|
||||||
|
-- This file is part of EthMAC.
|
||||||
|
--
|
||||||
|
-- EthMAC 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, version 2 of the License.
|
||||||
|
--
|
||||||
|
-- This code 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 code. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
--
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
-- Implementation of the SMI
|
||||||
|
-- Only write Access implemented
|
||||||
|
-- I think i won't implement read access because.........IT'S FUCKING USELESS
|
||||||
|
entity smi is
|
||||||
|
generic(
|
||||||
|
clockdiv : integer := 64
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
clk_i : in std_logic;
|
||||||
|
rst_i : in std_logic;
|
||||||
|
mdio_io : inout std_logic;
|
||||||
|
mdc_o : out std_logic;
|
||||||
|
busy_o : out std_logic;
|
||||||
|
data_o : out std_logic_vector(15 downto 0);
|
||||||
|
phyaddr_i : std_logic_vector(4 downto 0);
|
||||||
|
regaddr_i : std_logic_vector(4 downto 0);
|
||||||
|
data_i : in std_logic_vector(15 downto 0);
|
||||||
|
strb_i : in std_logic;
|
||||||
|
rw_i : in std_logic --Read/write. 0=write, 1=read
|
||||||
|
);
|
||||||
|
end entity smi;
|
||||||
|
|
||||||
|
architecture RTL of smi is
|
||||||
|
type smistate_t is (IDLE, PRE, SOF, OPC, PHYADDR, REGADDR, TURN, DATA, CONCL);
|
||||||
|
signal state_s : smistate_t;
|
||||||
|
signal fedge_strb_s : std_logic;
|
||||||
|
signal datashift_s : std_logic_vector(15 downto 0);
|
||||||
|
signal regaddr_s : std_logic_vector(4 downto 0);
|
||||||
|
signal phyaddr_s : std_logic_vector(4 downto 0);
|
||||||
|
signal bitcounter_s : integer range 0 to 32;
|
||||||
|
signal mdc_o_s : std_logic;
|
||||||
|
begin
|
||||||
|
mdc_o <= mdc_o_s;
|
||||||
|
|
||||||
|
div : process(clk_i, rst_i) is
|
||||||
|
variable counter : integer := 0;
|
||||||
|
begin
|
||||||
|
if rst_i = '1' then
|
||||||
|
fedge_strb_s <= '0';
|
||||||
|
counter := 0;
|
||||||
|
mdc_o_s <= '0';
|
||||||
|
elsif rising_edge(clk_i) then
|
||||||
|
fedge_strb_s <= '0';
|
||||||
|
counter := counter + 1;
|
||||||
|
if counter = clockdiv then
|
||||||
|
mdc_o_s <= not mdc_o_s;
|
||||||
|
counter := 0;
|
||||||
|
if mdc_o_s = '1' then
|
||||||
|
fedge_strb_s <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process div;
|
||||||
|
|
||||||
|
smishift : process(clk_i, rst_i) is
|
||||||
|
begin
|
||||||
|
if rst_i = '1' then
|
||||||
|
mdio_io <= '1';
|
||||||
|
state_s <= IDLE;
|
||||||
|
|
||||||
|
busy_o <= '1';
|
||||||
|
elsif rising_edge(clk_i) then
|
||||||
|
busy_o <= '1';
|
||||||
|
if state_s = IDLE then
|
||||||
|
mdio_io <= '1';
|
||||||
|
busy_o <= '0';
|
||||||
|
bitcounter_s <= 0;
|
||||||
|
if (strb_i = '1') then
|
||||||
|
state_s <= PRE;
|
||||||
|
busy_o <= '1';
|
||||||
|
--Load data
|
||||||
|
phyaddr_s <= phyaddr_i;
|
||||||
|
regaddr_s <= regaddr_i;
|
||||||
|
datashift_s <= data_i;
|
||||||
|
end if;
|
||||||
|
elsif state_s = CONCL then
|
||||||
|
mdio_io <= '1';
|
||||||
|
busy_o <= '0';
|
||||||
|
state_s <= IDLE;
|
||||||
|
bitcounter_s <= 0;
|
||||||
|
elsif fedge_strb_s = '1' then
|
||||||
|
mdio_io <= '1';
|
||||||
|
bitcounter_s <= bitcounter_s + 1;
|
||||||
|
case state_s is
|
||||||
|
when PRE =>
|
||||||
|
if fedge_strb_s = '1' then
|
||||||
|
--Mdio idle high for 32 cycles
|
||||||
|
if (bitcounter_s = 31) then
|
||||||
|
bitcounter_s <= 0;
|
||||||
|
state_s <= SOF;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when SOF =>
|
||||||
|
if bitcounter_s = 0 then
|
||||||
|
mdio_io <= '0';
|
||||||
|
elsif bitcounter_s = 1 then
|
||||||
|
bitcounter_s <= 0;
|
||||||
|
--Mdio idle high
|
||||||
|
state_s <= OPC;
|
||||||
|
end if;
|
||||||
|
when OPC => --Write OPCODE
|
||||||
|
if bitcounter_s = 0 then
|
||||||
|
if rw_i = '1' then
|
||||||
|
mdio_io <= '1';
|
||||||
|
else
|
||||||
|
mdio_io <= '0';
|
||||||
|
end if;
|
||||||
|
elsif bitcounter_s = 1 then
|
||||||
|
bitcounter_s <= 0;
|
||||||
|
if rw_i = '1' then
|
||||||
|
mdio_io <= '0';
|
||||||
|
else
|
||||||
|
mdio_io <= '1';
|
||||||
|
end if;
|
||||||
|
state_s <= PHYADDR;
|
||||||
|
end if;
|
||||||
|
when PHYADDR =>
|
||||||
|
if bitcounter_s = 4 then
|
||||||
|
bitcounter_s <= 0;
|
||||||
|
state_s <= REGADDR;
|
||||||
|
end if;
|
||||||
|
mdio_io <= phyaddr_s(4);
|
||||||
|
phyaddr_s <= phyaddr_s(3 downto 0) & '0';
|
||||||
|
when REGADDR =>
|
||||||
|
if bitcounter_s = 4 then
|
||||||
|
bitcounter_s <= 0;
|
||||||
|
state_s <= TURN;
|
||||||
|
end if;
|
||||||
|
mdio_io <= regaddr_s(4);
|
||||||
|
regaddr_s <= regaddr_s(3 downto 0) & '0';
|
||||||
|
when TURN =>
|
||||||
|
if rw_i = '1' then
|
||||||
|
mdio_io <= 'Z';
|
||||||
|
end if;
|
||||||
|
if bitcounter_s = 1 then
|
||||||
|
bitcounter_s <= 0;
|
||||||
|
state_s <= DATA;
|
||||||
|
end if;
|
||||||
|
when DATA =>
|
||||||
|
if bitcounter_s = 15 then
|
||||||
|
bitcounter_s <= 0;
|
||||||
|
state_s <= CONCL;
|
||||||
|
end if;
|
||||||
|
if rw_i = '1' then
|
||||||
|
mdio_io <= 'Z';
|
||||||
|
--Not implemented => =>
|
||||||
|
else
|
||||||
|
mdio_io <= datashift_s(15);
|
||||||
|
datashift_s <= datashift_s(14 downto 0) & '0';
|
||||||
|
end if;
|
||||||
|
when others =>
|
||||||
|
null; -- This should not happen
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process smishift;
|
||||||
|
|
||||||
|
data_o <= (others => '0');
|
||||||
|
|
||||||
|
end architecture RTL;
|
95
fifo.vhd
Normal file
95
fifo.vhd
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
library IEEE;
|
||||||
|
USE IEEE.STD_LOGIC_1164.ALL;
|
||||||
|
USE IEEE.NUMERIC_STD.ALL;
|
||||||
|
|
||||||
|
entity STD_FIFO is
|
||||||
|
Generic (
|
||||||
|
constant DATA_WIDTH : positive := 8;
|
||||||
|
constant FIFO_DEPTH : positive := 256
|
||||||
|
);
|
||||||
|
Port (
|
||||||
|
CLK : in STD_LOGIC;
|
||||||
|
RST : in STD_LOGIC;
|
||||||
|
WriteEn : in STD_LOGIC;
|
||||||
|
DataIn : in STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
|
||||||
|
ReadEn : in STD_LOGIC;
|
||||||
|
DataOut : out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
|
||||||
|
Empty : out STD_LOGIC;
|
||||||
|
Full : out STD_LOGIC
|
||||||
|
);
|
||||||
|
end STD_FIFO;
|
||||||
|
|
||||||
|
architecture Behavioral of STD_FIFO is
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
-- Memory Pointer Process
|
||||||
|
fifo_proc : process (CLK)
|
||||||
|
type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0);
|
||||||
|
variable Memory : FIFO_Memory;
|
||||||
|
|
||||||
|
variable Head : natural range 0 to FIFO_DEPTH - 1;
|
||||||
|
variable Tail : natural range 0 to FIFO_DEPTH - 1;
|
||||||
|
|
||||||
|
variable Looped : boolean;
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK) then
|
||||||
|
if RST = '1' then
|
||||||
|
Head := 0;
|
||||||
|
Tail := 0;
|
||||||
|
|
||||||
|
Looped := false;
|
||||||
|
|
||||||
|
Full <= '0';
|
||||||
|
Empty <= '1';
|
||||||
|
else
|
||||||
|
if (ReadEn = '1') then
|
||||||
|
if ((Looped = true) or (Head /= Tail)) then
|
||||||
|
-- Update data output
|
||||||
|
DataOut <= Memory(Tail);
|
||||||
|
|
||||||
|
-- Update Tail pointer as needed
|
||||||
|
if (Tail = FIFO_DEPTH - 1) then
|
||||||
|
Tail := 0;
|
||||||
|
|
||||||
|
Looped := false;
|
||||||
|
else
|
||||||
|
Tail := Tail + 1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if (WriteEn = '1') then
|
||||||
|
if ((Looped = false) or (Head /= Tail)) then
|
||||||
|
-- Write Data to Memory
|
||||||
|
Memory(Head) := DataIn;
|
||||||
|
|
||||||
|
-- Increment Head pointer as needed
|
||||||
|
if (Head = FIFO_DEPTH - 1) then
|
||||||
|
Head := 0;
|
||||||
|
|
||||||
|
Looped := true;
|
||||||
|
else
|
||||||
|
Head := Head + 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- Update Empty and Full flags
|
||||||
|
if (Head = Tail) then
|
||||||
|
if Looped then
|
||||||
|
Full <= '1';
|
||||||
|
else
|
||||||
|
Empty <= '1';
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
Empty <= '0';
|
||||||
|
Full <= '0';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
end Behavioral;
|
125
fifo_dc.vhd
Normal file
125
fifo_dc.vhd
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
-- VHDL netlist generated by SCUBA Diamond (64-bit) 3.10.0.111.2
|
||||||
|
-- Module Version: 5.8
|
||||||
|
--/usr/local/diamond/3.10_x64/ispfpga/bin/lin64/scuba -w -n fifo_dc -lang vhdl -synth synplify -bus_exp 7 -bb -arch xo2c00 -type ebfifo -depth 256 -width 8 -rwidth 8 -no_enable -pe 10 -pf 250
|
||||||
|
|
||||||
|
-- Thu Apr 5 20:50:27 2018
|
||||||
|
|
||||||
|
library IEEE;
|
||||||
|
use IEEE.std_logic_1164.all;
|
||||||
|
-- synopsys translate_off
|
||||||
|
library MACHXO2;
|
||||||
|
use MACHXO2.components.all;
|
||||||
|
-- synopsys translate_on
|
||||||
|
|
||||||
|
entity fifo_dc is
|
||||||
|
port (
|
||||||
|
Data: in std_logic_vector(7 downto 0);
|
||||||
|
WrClock: in std_logic;
|
||||||
|
RdClock: in std_logic;
|
||||||
|
WrEn: in std_logic;
|
||||||
|
RdEn: in std_logic;
|
||||||
|
Reset: in std_logic;
|
||||||
|
RPReset: in std_logic;
|
||||||
|
Q: out std_logic_vector(7 downto 0);
|
||||||
|
Empty: out std_logic;
|
||||||
|
Full: out std_logic;
|
||||||
|
AlmostEmpty: out std_logic;
|
||||||
|
AlmostFull: out std_logic);
|
||||||
|
end fifo_dc;
|
||||||
|
|
||||||
|
architecture Structure of fifo_dc is
|
||||||
|
|
||||||
|
-- internal signal declarations
|
||||||
|
signal scuba_vhi: std_logic;
|
||||||
|
signal Empty_int: std_logic;
|
||||||
|
signal Full_int: std_logic;
|
||||||
|
signal scuba_vlo: std_logic;
|
||||||
|
|
||||||
|
-- local component declarations
|
||||||
|
component VHI
|
||||||
|
port (Z: out std_logic);
|
||||||
|
end component;
|
||||||
|
component VLO
|
||||||
|
port (Z: out std_logic);
|
||||||
|
end component;
|
||||||
|
component FIFO8KB
|
||||||
|
generic (FULLPOINTER1 : in String; FULLPOINTER : in String;
|
||||||
|
AFPOINTER1 : in String; AFPOINTER : in String;
|
||||||
|
AEPOINTER1 : in String; AEPOINTER : in String;
|
||||||
|
ASYNC_RESET_RELEASE : in String; RESETMODE : in String;
|
||||||
|
GSR : in String; CSDECODE_R : in String;
|
||||||
|
CSDECODE_W : in String; REGMODE : in String;
|
||||||
|
DATA_WIDTH_R : in Integer; DATA_WIDTH_W : in Integer);
|
||||||
|
port (DI0: in std_logic; DI1: in std_logic; DI2: in std_logic;
|
||||||
|
DI3: in std_logic; DI4: in std_logic; DI5: in std_logic;
|
||||||
|
DI6: in std_logic; DI7: in std_logic; DI8: in std_logic;
|
||||||
|
DI9: in std_logic; DI10: in std_logic; DI11: in std_logic;
|
||||||
|
DI12: in std_logic; DI13: in std_logic;
|
||||||
|
DI14: in std_logic; DI15: in std_logic;
|
||||||
|
DI16: in std_logic; DI17: in std_logic;
|
||||||
|
CSW0: in std_logic; CSW1: in std_logic;
|
||||||
|
CSR0: in std_logic; CSR1: in std_logic;
|
||||||
|
FULLI: in std_logic; EMPTYI: in std_logic;
|
||||||
|
WE: in std_logic; RE: in std_logic; ORE: in std_logic;
|
||||||
|
CLKW: in std_logic; CLKR: in std_logic; RST: in std_logic;
|
||||||
|
RPRST: in std_logic; DO0: out std_logic;
|
||||||
|
DO1: out std_logic; DO2: out std_logic;
|
||||||
|
DO3: out std_logic; DO4: out std_logic;
|
||||||
|
DO5: out std_logic; DO6: out std_logic;
|
||||||
|
DO7: out std_logic; DO8: out std_logic;
|
||||||
|
DO9: out std_logic; DO10: out std_logic;
|
||||||
|
DO11: out std_logic; DO12: out std_logic;
|
||||||
|
DO13: out std_logic; DO14: out std_logic;
|
||||||
|
DO15: out std_logic; DO16: out std_logic;
|
||||||
|
DO17: out std_logic; EF: out std_logic;
|
||||||
|
AEF: out std_logic; AFF: out std_logic; FF: out std_logic);
|
||||||
|
end component;
|
||||||
|
attribute syn_keep : boolean;
|
||||||
|
attribute NGD_DRC_MASK : integer;
|
||||||
|
attribute NGD_DRC_MASK of Structure : architecture is 1;
|
||||||
|
|
||||||
|
begin
|
||||||
|
-- component instantiation statements
|
||||||
|
scuba_vhi_inst: VHI
|
||||||
|
port map (Z=>scuba_vhi);
|
||||||
|
|
||||||
|
scuba_vlo_inst: VLO
|
||||||
|
port map (Z=>scuba_vlo);
|
||||||
|
|
||||||
|
fifo_dc_0_0: FIFO8KB
|
||||||
|
generic map (FULLPOINTER1=> "0b00111111110000", FULLPOINTER=> "0b01000000000000",
|
||||||
|
AFPOINTER1=> "0b00111110010000", AFPOINTER=> "0b00111110100000",
|
||||||
|
AEPOINTER1=> "0b00000010110000", AEPOINTER=> "0b00000010100000",
|
||||||
|
ASYNC_RESET_RELEASE=> "SYNC", GSR=> "DISABLED", RESETMODE=> "ASYNC",
|
||||||
|
REGMODE=> "NOREG", CSDECODE_R=> "0b11", CSDECODE_W=> "0b11",
|
||||||
|
DATA_WIDTH_R=> 18, DATA_WIDTH_W=> 18)
|
||||||
|
port map (DI0=>Data(0), DI1=>Data(1), DI2=>Data(2), DI3=>Data(3),
|
||||||
|
DI4=>Data(4), DI5=>Data(5), DI6=>Data(6), DI7=>Data(7),
|
||||||
|
DI8=>scuba_vlo, DI9=>scuba_vlo, DI10=>scuba_vlo,
|
||||||
|
DI11=>scuba_vlo, DI12=>scuba_vlo, DI13=>scuba_vlo,
|
||||||
|
DI14=>scuba_vlo, DI15=>scuba_vlo, DI16=>scuba_vlo,
|
||||||
|
DI17=>scuba_vlo, CSW0=>scuba_vhi, CSW1=>scuba_vhi,
|
||||||
|
CSR0=>scuba_vhi, CSR1=>scuba_vhi, FULLI=>Full_int,
|
||||||
|
EMPTYI=>Empty_int, WE=>WrEn, RE=>RdEn, ORE=>RdEn,
|
||||||
|
CLKW=>WrClock, CLKR=>RdClock, RST=>Reset, RPRST=>RPReset,
|
||||||
|
DO0=>open, DO1=>open, DO2=>open, DO3=>open, DO4=>open,
|
||||||
|
DO5=>open, DO6=>open, DO7=>open, DO8=>open, DO9=>Q(0),
|
||||||
|
DO10=>Q(1), DO11=>Q(2), DO12=>Q(3), DO13=>Q(4), DO14=>Q(5),
|
||||||
|
DO15=>Q(6), DO16=>Q(7), DO17=>open, EF=>Empty_int,
|
||||||
|
AEF=>AlmostEmpty, AFF=>AlmostFull, FF=>Full_int);
|
||||||
|
|
||||||
|
Empty <= Empty_int;
|
||||||
|
Full <= Full_int;
|
||||||
|
end Structure;
|
||||||
|
|
||||||
|
-- synopsys translate_off
|
||||||
|
library MACHXO2;
|
||||||
|
configuration Structure_CON of fifo_dc is
|
||||||
|
for Structure
|
||||||
|
for all:VHI use entity MACHXO2.VHI(V); end for;
|
||||||
|
for all:VLO use entity MACHXO2.VLO(V); end for;
|
||||||
|
for all:FIFO8KB use entity MACHXO2.FIFO8KB(V); end for;
|
||||||
|
end for;
|
||||||
|
end Structure_CON;
|
||||||
|
|
||||||
|
-- synopsys translate_on
|
372
top.vhd
Normal file
372
top.vhd
Normal file
@ -0,0 +1,372 @@
|
|||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Title : Ethernet controlled WS2812b
|
||||||
|
-- Project :
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- File : top.vhd
|
||||||
|
-- Author : Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
-- Company :
|
||||||
|
-- Created : 2018-04-05
|
||||||
|
-- Last update: 2018-04-06
|
||||||
|
-- Platform :
|
||||||
|
-- Standard : VHDL'93/02
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Description:
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-- Copyright (c) 2018
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity top is
|
||||||
|
|
||||||
|
port (
|
||||||
|
clk : in std_logic;
|
||||||
|
rst_hw : in std_logic;
|
||||||
|
mdio : inout std_logic;
|
||||||
|
mdc : out std_logic;
|
||||||
|
rx : in std_logic_vector(1 downto 0);
|
||||||
|
dv : in std_logic;
|
||||||
|
led1 : out std_logic;
|
||||||
|
led2 : out std_logic;
|
||||||
|
dat_cnt : out std_logic_vector(3 downto 0);
|
||||||
|
ws_out : out std_logic);
|
||||||
|
|
||||||
|
end entity top;
|
||||||
|
|
||||||
|
architecture RTL of top is
|
||||||
|
constant DELAYCNTVAL : integer := 100000;
|
||||||
|
constant DEFMAC : std_logic_vector(47 downto 0) := x"00DEADBEEF00";
|
||||||
|
|
||||||
|
type smi_state_t is (IDLE, STROBE);
|
||||||
|
type smi_init_state_t is (RESET, INIT, DELAY, INIT_COMPLETE);
|
||||||
|
type ws_send_t is (WS_READY, WS_SYNC, WS_RED, WS_GREEN, WS_BLUE, WS_PIPE, WS_POST);
|
||||||
|
type receive_t is (PRE, DESTMAC, HEADER, RECV, WAITFORACK);
|
||||||
|
|
||||||
|
signal rst : std_logic;
|
||||||
|
signal dat_cnt_s : unsigned(3 downto 0);
|
||||||
|
|
||||||
|
signal sendstate : smi_state_t;
|
||||||
|
signal initstate : smi_init_state_t := RESET;
|
||||||
|
signal rst_rxtx : std_logic;
|
||||||
|
signal delaycounter : unsigned(19 downto 0);
|
||||||
|
signal smi_reg : std_logic_vector(4 downto 0);
|
||||||
|
signal smi_dat : std_logic_vector(15 downto 0);
|
||||||
|
signal smi_strb : std_logic;
|
||||||
|
signal smi_busy : std_logic;
|
||||||
|
---
|
||||||
|
signal sof : std_logic;
|
||||||
|
signal eof : std_logic;
|
||||||
|
signal eth_dat : std_logic_vector(7 downto 0);
|
||||||
|
signal eth_strb : std_logic;
|
||||||
|
signal crc_valid : std_logic;
|
||||||
|
--
|
||||||
|
signal fifo_in : std_logic_vector(7 downto 0);
|
||||||
|
signal fifo_out : std_logic_vector(7 downto 0);
|
||||||
|
signal fifo_wr : std_logic;
|
||||||
|
signal fifo_rd : std_logic;
|
||||||
|
signal fifo_rst : std_logic;
|
||||||
|
signal fifo_full : std_logic;
|
||||||
|
signal fifo_empty : std_logic;
|
||||||
|
--
|
||||||
|
signal fifo_data_avail : std_logic;
|
||||||
|
signal fifo_data_ack : std_logic;
|
||||||
|
signal recv_state : receive_t;
|
||||||
|
signal mac : std_logic_vector(47 downto 0);
|
||||||
|
signal recv_cnt : integer range 0 to 15;
|
||||||
|
--
|
||||||
|
signal ws_busy : std_logic;
|
||||||
|
signal ws_strb : std_logic;
|
||||||
|
signal red : unsigned(7 downto 0);
|
||||||
|
signal green : unsigned(7 downto 0);
|
||||||
|
signal blue : unsigned(7 downto 0);
|
||||||
|
--
|
||||||
|
signal ws_state : ws_send_t;
|
||||||
|
|
||||||
|
begin -- architecture RTL
|
||||||
|
|
||||||
|
rst <= not rst_hw;
|
||||||
|
|
||||||
|
smi_1 : entity work.smi
|
||||||
|
generic map (
|
||||||
|
clockdiv => 64)
|
||||||
|
port map (
|
||||||
|
clk_i => clk,
|
||||||
|
rst_i => rst,
|
||||||
|
mdio_io => mdio,
|
||||||
|
mdc_o => mdc,
|
||||||
|
busy_o => smi_busy,
|
||||||
|
data_o => open,
|
||||||
|
phyaddr_i => "00001",
|
||||||
|
regaddr_i => smi_reg,
|
||||||
|
data_i => smi_dat,
|
||||||
|
strb_i => smi_strb,
|
||||||
|
rw_i => '0');
|
||||||
|
|
||||||
|
|
||||||
|
ethmac_rx_1 : entity work.ethmac_rx
|
||||||
|
port map (
|
||||||
|
clk_50 => clk,
|
||||||
|
rst => rst_rxtx,
|
||||||
|
rmii_rx => rx,
|
||||||
|
rmii_dv => dv,
|
||||||
|
start_of_frame => sof,
|
||||||
|
end_of_frame => eof,
|
||||||
|
data_out => eth_dat,
|
||||||
|
data_strb => eth_strb,
|
||||||
|
crc_check_valid => crc_valid);
|
||||||
|
|
||||||
|
-- fifo_dc_1 : entity work.fifo_dc
|
||||||
|
-- port map (
|
||||||
|
-- Data => fifo_in,
|
||||||
|
-- WrClock => clk,
|
||||||
|
-- RdClock => clk,
|
||||||
|
-- WrEn => fifo_wr,
|
||||||
|
-- RdEn => fifo_rd,
|
||||||
|
-- Reset => fifo_rst,
|
||||||
|
-- RPReset => fifo_rst,
|
||||||
|
-- Q => fifo_out,
|
||||||
|
-- Empty => fifo_empty,
|
||||||
|
-- Full => fifo_full,
|
||||||
|
-- AlmostEmpty => open,
|
||||||
|
-- AlmostFull => open);
|
||||||
|
STD_FIFO_1 : entity work.STD_FIFO
|
||||||
|
generic map (
|
||||||
|
DATA_WIDTH => 8,
|
||||||
|
FIFO_DEPTH => 256)
|
||||||
|
port map (
|
||||||
|
CLK => clk,
|
||||||
|
RST => fifo_rst,
|
||||||
|
WriteEn => fifo_wr,
|
||||||
|
DataIn => fifo_in,
|
||||||
|
ReadEn => fifo_rd,
|
||||||
|
DataOut => fifo_out,
|
||||||
|
Empty => fifo_empty,
|
||||||
|
Full => fifo_full);
|
||||||
|
|
||||||
|
wsphy1 : entity work.ws2812bphy
|
||||||
|
generic map (
|
||||||
|
HIGH1 => 40,
|
||||||
|
LOW1 => 23,
|
||||||
|
HIGH0 => 20,
|
||||||
|
LOW0 => 43)
|
||||||
|
port map (
|
||||||
|
clk => clk,
|
||||||
|
rst => rst,
|
||||||
|
busy => ws_busy,
|
||||||
|
ws_out => ws_out,
|
||||||
|
strb => ws_strb,
|
||||||
|
red => red,
|
||||||
|
green => green,
|
||||||
|
blue => blue);
|
||||||
|
|
||||||
|
initphy : process(clk, rst) is
|
||||||
|
procedure sendsmi(regaddr : in std_logic_vector(4 downto 0);
|
||||||
|
data : in std_logic_vector(15 downto 0);
|
||||||
|
nextstate : in smi_init_state_t) is
|
||||||
|
begin
|
||||||
|
case sendstate is
|
||||||
|
when IDLE =>
|
||||||
|
smi_reg <= regaddr;
|
||||||
|
smi_dat <= data;
|
||||||
|
if smi_busy = '0' then
|
||||||
|
smi_strb <= '1';
|
||||||
|
sendstate <= STROBE;
|
||||||
|
end if;
|
||||||
|
when STROBE =>
|
||||||
|
initstate <= nextstate;
|
||||||
|
sendstate <= IDLE;
|
||||||
|
end case;
|
||||||
|
end procedure sendsmi;
|
||||||
|
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
smi_reg <= (others => '0');
|
||||||
|
smi_dat <= (others => '0');
|
||||||
|
smi_strb <= '0';
|
||||||
|
rst_rxtx <= '1';
|
||||||
|
initstate <= RESET;
|
||||||
|
sendstate <= IDLE;
|
||||||
|
delaycounter <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
smi_strb <= '0';
|
||||||
|
rst_rxtx <= '1';
|
||||||
|
case initstate is
|
||||||
|
when RESET =>
|
||||||
|
sendsmi((others => '0'), x"8000", DELAY);
|
||||||
|
when DELAY =>
|
||||||
|
delaycounter <= delaycounter + 1;
|
||||||
|
if delaycounter = DELAYCNTVAL then -- Set to 100000
|
||||||
|
initstate <= INIT;
|
||||||
|
end if;
|
||||||
|
when INIT =>
|
||||||
|
sendsmi((others => '0'), "00" & '1' & '1' & "000" & '1' & "00000000", INIT_COMPLETE);
|
||||||
|
when INIT_COMPLETE =>
|
||||||
|
initstate <= INIT_COMPLETE;
|
||||||
|
rst_rxtx <= '0';
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process initphy;
|
||||||
|
|
||||||
|
|
||||||
|
receive_fifo : process (clk, rst) is
|
||||||
|
begin -- process receive_fifo
|
||||||
|
if rst = '1' then -- asynchronous reset (active high)
|
||||||
|
fifo_rst <= '1';
|
||||||
|
fifo_wr <= '0';
|
||||||
|
fifo_in <= (others => '0');
|
||||||
|
fifo_data_avail <= '0';
|
||||||
|
recv_state <= PRE;
|
||||||
|
dat_cnt_s <= (others => '0');
|
||||||
|
led1 <= '1';
|
||||||
|
led2 <= '1';
|
||||||
|
recv_cnt <= 0;
|
||||||
|
mac <= (others => '0');
|
||||||
|
elsif rising_edge(clk) then -- rising clock edge
|
||||||
|
fifo_rst <= '0';
|
||||||
|
fifo_wr <= '0';
|
||||||
|
case recv_state is
|
||||||
|
when PRE =>
|
||||||
|
if sof = '1' then
|
||||||
|
recv_cnt <= 0;
|
||||||
|
mac <= (others => '0');
|
||||||
|
recv_state <= DESTMAC;
|
||||||
|
led1 <= '1';
|
||||||
|
led2 <= '1';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when DESTMAC =>
|
||||||
|
if eof = '1' then
|
||||||
|
recv_state <= PRE;
|
||||||
|
elsif eth_strb = '1' then
|
||||||
|
recv_cnt <= recv_cnt + 1;
|
||||||
|
mac <= mac(39 downto 0) & eth_dat;
|
||||||
|
if recv_cnt = 5 then
|
||||||
|
recv_cnt <= 0;
|
||||||
|
recv_state <= HEADER;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when HEADER =>
|
||||||
|
led1 <= '0';
|
||||||
|
if eof = '1' then
|
||||||
|
recv_state <= PRE;
|
||||||
|
elsif eth_strb = '1' then
|
||||||
|
recv_cnt <= recv_cnt + 1;
|
||||||
|
if recv_cnt = 7 then
|
||||||
|
if mac = DEFMAC then
|
||||||
|
recv_state <= RECV;
|
||||||
|
dat_cnt_s <= (others =>'0');
|
||||||
|
else
|
||||||
|
recv_state <= PRE;
|
||||||
|
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when RECV =>
|
||||||
|
led2 <= '0';
|
||||||
|
if eth_strb = '1' and fifo_full /= '1' then
|
||||||
|
fifo_in <= eth_dat;
|
||||||
|
fifo_wr <= '1';
|
||||||
|
dat_cnt_s <= dat_cnt_s +1;
|
||||||
|
end if;
|
||||||
|
if eof = '1' then
|
||||||
|
if crc_valid = '1' then-- or crc_valid = '0' then
|
||||||
|
recv_state <= WAITFORACK;
|
||||||
|
fifo_data_avail <= '1';
|
||||||
|
--led2 <= '0';
|
||||||
|
else
|
||||||
|
--led2 <= '1';
|
||||||
|
fifo_rst <= '1';
|
||||||
|
recv_state <= PRE;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when WAITFORACK =>
|
||||||
|
|
||||||
|
fifo_data_avail <= '1';
|
||||||
|
if fifo_data_ack = '1' then
|
||||||
|
recv_state <= PRE;
|
||||||
|
fifo_data_avail <= '0';
|
||||||
|
-- fifo_rst <= '1';
|
||||||
|
end if;
|
||||||
|
when others => null;
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process receive_fifo;
|
||||||
|
|
||||||
|
ws_write : process (clk, rst) is
|
||||||
|
-- variable ws_send_cnt : integer range 0 to 7 := 0;
|
||||||
|
begin -- process ws_write
|
||||||
|
if rst = '1' then -- asynchronous reset (active high)
|
||||||
|
red <= (others => '0');
|
||||||
|
green <= (others => '0');
|
||||||
|
blue <= (others => '0');
|
||||||
|
ws_strb <= '0';
|
||||||
|
fifo_rd <= '0';
|
||||||
|
fifo_data_ack <= '0';
|
||||||
|
ws_state <= WS_READY;
|
||||||
|
elsif rising_edge(clk) then -- rising clock edge
|
||||||
|
ws_strb <= '0';
|
||||||
|
fifo_rd <= '0';
|
||||||
|
fifo_data_ack <= '0';
|
||||||
|
case ws_state is
|
||||||
|
when WS_READY =>
|
||||||
|
if fifo_data_avail = '1' then
|
||||||
|
if fifo_empty = '0' then
|
||||||
|
ws_state <= WS_SYNC;
|
||||||
|
fifo_rd <= '1'; -- read red
|
||||||
|
else
|
||||||
|
ws_state <= WS_POST;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when WS_SYNC =>
|
||||||
|
if fifo_empty = '1' then
|
||||||
|
ws_state <= WS_POST;
|
||||||
|
else
|
||||||
|
fifo_rd <= '1'; --read green
|
||||||
|
ws_state <= WS_RED;
|
||||||
|
end if;
|
||||||
|
when WS_RED =>
|
||||||
|
if fifo_empty = '1' then
|
||||||
|
ws_state <= WS_POST;
|
||||||
|
else
|
||||||
|
fifo_rd <= '1'; --read blue
|
||||||
|
red <= unsigned(fifo_out);
|
||||||
|
ws_state <= WS_GREEN;
|
||||||
|
end if;
|
||||||
|
when WS_GREEN =>
|
||||||
|
if fifo_empty = '1' then
|
||||||
|
ws_state <= WS_POST;
|
||||||
|
else
|
||||||
|
green <= unsigned(fifo_out);
|
||||||
|
ws_state <= WS_BLUE;
|
||||||
|
end if;
|
||||||
|
when WS_BLUE =>
|
||||||
|
blue <= unsigned(fifo_out);
|
||||||
|
ws_state <= WS_PIPE;
|
||||||
|
when WS_PIPE =>
|
||||||
|
if ws_busy = '0' and ws_strb = '0' then
|
||||||
|
ws_strb <= '1';
|
||||||
|
if fifo_empty = '0' then
|
||||||
|
ws_state <= WS_SYNC;
|
||||||
|
fifo_rd <= '1'; -- read
|
||||||
|
else
|
||||||
|
ws_state <= WS_POST;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
when WS_POST =>
|
||||||
|
if ws_busy = '0' and fifo_data_ack = '0' then
|
||||||
|
fifo_data_ack <= '1';
|
||||||
|
elsif fifo_data_ack = '1' and fifo_data_avail = '1' then
|
||||||
|
ws_state <= WS_READY;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
end if;
|
||||||
|
end process ws_write;
|
||||||
|
dat_cnt <= std_logic_vector(dat_cnt_s);
|
||||||
|
|
||||||
|
end architecture RTL;
|
121
ws2812/ws2812bphy.vhd
Normal file
121
ws2812/ws2812bphy.vhd
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity ws2812bphy is
|
||||||
|
generic(
|
||||||
|
constant HIGH1 : integer := 40;
|
||||||
|
constant LOW1 : integer := 23;
|
||||||
|
constant HIGH0 : integer := 20;
|
||||||
|
constant LOW0 : integer := 43);
|
||||||
|
port(
|
||||||
|
clk : in std_logic;
|
||||||
|
rst : in std_logic;
|
||||||
|
busy : out std_logic;
|
||||||
|
ws_out : out std_logic;
|
||||||
|
strb : in std_logic;
|
||||||
|
red : in unsigned(7 downto 0);
|
||||||
|
green : in unsigned(7 downto 0);
|
||||||
|
blue : in unsigned(7 downto 0));
|
||||||
|
end entity ws2812bphy;
|
||||||
|
|
||||||
|
architecture RTL of ws2812bphy is
|
||||||
|
|
||||||
|
type ws_output_state_t is (IDLE, TRANSMITTING, INTERLEDDELAY);
|
||||||
|
signal ws_output_state : ws_output_state_t;
|
||||||
|
|
||||||
|
type bitstate_t is (LOW, HIGH);
|
||||||
|
signal bitstate : bitstate_t;
|
||||||
|
|
||||||
|
begin
|
||||||
|
ws_output : process(clk, rst) is
|
||||||
|
variable counter : integer range 0 to 255 := 0;
|
||||||
|
|
||||||
|
variable color_vector : std_logic_vector(23 downto 0);
|
||||||
|
variable bitnum : integer range 0 to 23;
|
||||||
|
begin
|
||||||
|
if rst = '1' then
|
||||||
|
ws_output_state <= IDLE;
|
||||||
|
color_vector := (others => '0');
|
||||||
|
counter := 0;
|
||||||
|
bitstate <= LOW;
|
||||||
|
bitnum := 0;
|
||||||
|
elsif rising_edge(clk) then
|
||||||
|
case ws_output_state is
|
||||||
|
when IDLE =>
|
||||||
|
bitstate <= LOW;
|
||||||
|
if strb = '1' then
|
||||||
|
ws_output_state <= TRANSMITTING;
|
||||||
|
bitnum := 23;
|
||||||
|
color_vector := std_logic_vector(green) & std_logic_vector(red) & std_logic_vector(blue);
|
||||||
|
counter := 0;
|
||||||
|
bitstate <= HIGH;
|
||||||
|
end if;
|
||||||
|
when TRANSMITTING =>
|
||||||
|
case bitstate is
|
||||||
|
when HIGH =>
|
||||||
|
if color_vector(bitnum) = '1' then
|
||||||
|
if counter < HIGH1 - 1 then
|
||||||
|
counter := counter + 1;
|
||||||
|
else
|
||||||
|
bitstate <= LOW;
|
||||||
|
counter := 0;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
if counter < HIGH0 -1 then
|
||||||
|
counter := counter + 1;
|
||||||
|
else
|
||||||
|
bitstate <= LOW;
|
||||||
|
counter := 0;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
when LOW =>
|
||||||
|
if color_vector(bitnum) = '1' then
|
||||||
|
if counter < LOW1 -1 then
|
||||||
|
counter := counter + 1;
|
||||||
|
else
|
||||||
|
bitstate <= HIGH;
|
||||||
|
counter := 0;
|
||||||
|
if bitnum = 0 then
|
||||||
|
ws_output_state <= INTERLEDDELAY;
|
||||||
|
counter := 0;
|
||||||
|
bitstate <= LOW;
|
||||||
|
else
|
||||||
|
bitnum := bitnum - 1;
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
if counter < LOW0 - 1 then
|
||||||
|
counter := counter + 1;
|
||||||
|
else
|
||||||
|
bitstate <= HIGH;
|
||||||
|
counter := 0;
|
||||||
|
|
||||||
|
if bitnum = 0 then
|
||||||
|
ws_output_state <= INTERLEDDELAY;
|
||||||
|
counter := 0;
|
||||||
|
bitstate <= LOW;
|
||||||
|
else
|
||||||
|
bitnum := bitnum - 1;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
|
||||||
|
when INTERLEDDELAY =>
|
||||||
|
if counter < HIGH1+LOW1+LOW1 then
|
||||||
|
counter := counter + 1;
|
||||||
|
else
|
||||||
|
counter := 0;
|
||||||
|
ws_output_state <= IDLE;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
end case;
|
||||||
|
end if;
|
||||||
|
end process ws_output;
|
||||||
|
busy <= '0' when ws_output_state = IDLE else '1';
|
||||||
|
ws_out <= '1' when bitstate = HIGH else '0';
|
||||||
|
|
||||||
|
end architecture RTL;
|
Loading…
Reference in New Issue
Block a user