I think the best thing to do is start from scratch with a good design plan and do this correctly. You guys have been really helpful so far and I really appreciate it. Perhaps you can let me know if I'm on the right track?
Here's what I'm working on. I need to store ethernet frames in SRAM so that I can retrieve them later.
An ethernet frame contains a preamble, a start frame delimiter, and then a bunch of other stuff. When I receive a frame, it will arrive with a validin signal. The validin signal will be high at some point between the beginning of the preamble and right before the start frame delimiter and stay high as long as the frame is valid. I want to store everything from the start frame delimiter to the end of the frame in memory. I'll also want to add my own delimiter to let me know when I've reached the end of the frame.
At some point I will want to retrieve these frames from memory but before I send them out, I need to attach a preamble to the front of them. I also need to preserve a minimum frame gap between two consecutive frames that I read out of memory so I want to write out 12 bytes of zeros.
Here's a diagram of what it looks like in my head:
http://img143.imageshack.us/img143/3365/design.png In the front I have 4 2-bit shift registers to check for the start frame delimiter (1010 1011). I'm doing everything in 4 bits because thats what I get on my input. When I see the frame, I start writing the entire frame to memory until validin goes low, and then I write 24 nibs of 1's to signify the end of the frame.
On the other side of memory I have a 4 1-bit shift registers which hold the data coming out of memory. First I look for the start frame delimiter, if I find it, I load a preamble into the 4-24bit shift registers, and then start sending it out until I count 24 consecutive "1111"s in the 4 1-bit shift registers which signifies the end of frame delimiter. At this point there should be 24 nibs of 1's in the 4-24bit shift registers. I parallel load 24 nibs of 0's to keep a gap between frames. Then I stop reading from memory and allow all of those 0's to shift out of the 24 bit registers. At this point, I'm ready to start again.
It's fairly simple with a few complexities. I think its just important to make sure I get started out on the right foot.
Here's my starting skeleton (I remembered to register all of the inputs):
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity fixer is
port
(
clk,reset : in std_logic;
input: in std_logic_vector(3 downto 0); -- the input ethernet frame
validin: in std_logic; --the valid signal that we get
readEN: in std_logic; --high when we want to read from memory
validout: out std_logic; --high when we're sending a valid frame out
output : out std_logic_vector(3 downto 0) --output has value if we're reading
);
end fixer;
architecture structure of fixer is
--registering inputs
signal reg_validin : std_logic;
signal reg_input : std_logic_vector(3 downto 0);
signal reg_readEN : std_logic;
--------------------------------
signal wren : std_logic; -- memory write enable
signal load: std_logic; -- load enable for the 24 bit shift registers
signal stop: std_logic; -- tells memory not to read and the 1 bit shift registers not to change their value
signal sfd: std_logic_vector(7 downto 0); -- parallel output of 4 - 2 bit shift registers
signal qin : std_logic_vector (3 downto 0); --input to memory
signal send: std_logic_vector(3 downto 0); --output of shift set of shift registers, to memory unless we're loading our end of frame delimiter
signal hold1: std_logic_vector (3 downto 0); --output of memory
signal hold2: std_logic_vector (3 downto 0); --output of 4 - 2 bit shift registers and input to 4 - 24 bit shift registers
signal address: std_logic_vector(14 downto 0);--address to read and write from memory at
signal outload0: std_logic_vector(23 downto 0); --vectors to load into the 24 bit shift registers
signal outload1: std_logic_vector(23 downto 0);
signal outload2: std_logic_vector(23 downto 0);
signal outload3: std_logic_vector(23 downto 0);
component shiftreg2 is
PORT
(
clock : IN STD_LOGIC ;
sclr : IN STD_LOGIC ;
shiftin : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (1 DOWNTO 0);
shiftout : OUT STD_LOGIC
);
end component;
component framestore is
port
(
clk,reset : in std_logic;
input: in std_logic_vector(3 downto 0); -- the input ethernet frame
address: in std_logic_vector(14 downto 0);
valid: in std_logic; --valid signal that comes with input
readEN: in std_logic; --high when we want to read from memory
output : out std_logic_vector(3 downto 0) --output, has value if we're reading
);
end component;
component shiftreg1 IS
PORT
(
clock : IN STD_LOGIC ;
enable : IN STD_LOGIC ;
sclr : IN STD_LOGIC ;
shiftin : IN STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
shiftout : OUT STD_LOGIC
);
END component;
component shiftreg24 is
PORT
(
clock : IN STD_LOGIC ;
data : IN STD_LOGIC_VECTOR (23 DOWNTO 0);
load : IN STD_LOGIC ;
sclr : IN STD_LOGIC ;
shiftin : IN STD_LOGIC ;
shiftout : OUT STD_LOGIC
);
end component;
begin
process(clk,reset)
begin
if(reset = '1') then
wren <= '0';
load <= '0';
stop <= '0';
address <= "000000000000000";
outload0 <= "000000000000000000000000";
outload1 <= "000000000000000000000000";
outload2 <= "000000000000000000000000";
outload3 <= "000000000000000000000000";
elsif(clk'event and clk = '1') then
--register inputs
reg_input <= input;
reg_validin <= validin;
reg_readEN <= readEN;
--figuring out address
--writing to memory
--reading from memory
end if;
end process;
--input to memory
bit3in: shiftreg port map(clk,reset,input(3),sfd(7 downto 6),send(3));
bit2in: shiftreg port map(clk,reset,input(2),sfd(5 downto 4),send(2));
bit1in: shiftreg port map(clk,reset,input(1),sfd(3 downto 2),send(1));
bit0in: shiftreg port map(clk,reset,input(0),sfd(1 downto 0),send(0));
--memory
mem: framestore port map(clk,reset,qin,address,wren,readEN and not stop,hold1);
--output of memory
bit3hold: shiftreg1 port map(clk,readEN and not stop,reset,hold1(3),hold2(3));
bit2hold: shiftreg1 port map(clk,readEN and not stop,reset,hold1(2),hold2(2));
bit1hold: shiftreg1 port map(clk,readEN and not stop,reset,hold1(1),hold2(1));
bit0hold: shiftreg1 port map(clk,readEN and not stop,reset,hold1(0),hold2(0));
--24 bit shift registers
bit3out: shiftreg24 port map(clk,outload3,load,reset,hold2(3),output(3));
bit2out: shiftreg24 port map(clk,outload2,load,reset,hold2(2),output(2));
bit1out: shiftreg24 port map(clk,outload1,load,reset,hold2(1),output(1));
bit0out: shiftreg24 port map(clk,outload0,load,reset,hold2(0),output(0));
end structure;