I'm having problems implementing Verilog Test Fixture to simulate my design - testing

I'm a beginner at vhdl and I'm trying to make a 8 bit divider using shift and subtract method. The code for the divider is okay, I guess, but I'm having problems in simulating the inputs. When I use the Verilog test fixture, my inputs which should be (dividend=51 [00110011b], divisor=19 [00010011b]) always end up becoming (dividend=49 [00110001b], divisor=49 [00110001b])) in iSim, and then the outputs (Quotient and remainder = xxxxxxx (unknown)) instead of (quotient=2[00000010b] and remainder=13 [00001101b])...
As I mentioned before, I'm a beginner at vhdl and I've been at this for five hours, I've tried my best to search for a solution online, but failed.... so any help or alternative solution would be greatly appreciated.
I'm using Xilinx ISE 14.3 and iSim.
Here is the code for the 8 bit binary divider.
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
use IEEE.STD_LOGIC_ARITH.all;
entity division is
generic(SIZE: INTEGER := 8);
port(reset: in STD_LOGIC; --reset
en: in STD_LOGIC; --enable
clk: in STD_LOGIC; --clock
num: in STD_LOGIC_VECTOR((SIZE - 1) downto 0); --dividend
den: in STD_LOGIC_VECTOR((SIZE - 1) downto 0); --divisor
res: out STD_LOGIC_VECTOR((SIZE - 1) downto 0); --result/quotient
rm: out STD_LOGIC_VECTOR((SIZE - 1) downto 0) --remainder
);
end division;
architecture behav of division is
signal bufreg: STD_LOGIC_VECTOR((2 * SIZE - 1) downto 0); --signal array to hold both accumulator and dividend registers as one i.e bufreg(18 bits)
signal dbuf: STD_LOGIC_VECTOR((SIZE - 1) downto 0); --signal array to hold the divisor
signal count: INTEGER range 0 to SIZE; --count to determine when to stop
alias ADreg is bufreg((2 * SIZE - 1) downto SIZE); --ADreg is is alias for top half of bufreg register(17th to 9th bit)
alias DVNDreg is bufreg((SIZE - 1) downto 0); --DVNDreg is is alias for bottom half of bufreg register(8th to 0th bit)
begin
--our process begins here
p_001: process(reset, en, clk)
begin
if reset = '1' then
res <= (others => '0');
rm <= (others => '0');
count <= 0;
elsif rising_edge(clk) then
if en = '1' then
case count is
when 0 =>
ADreg <= (others => '0');
DVNDreg <= num;
dbuf <= den;
res <= DVNDreg;
rm <= ADreg;
count <= count + 1;
when others =>
if bufreg((2 * SIZE - 2) downto (SIZE - 1)) >= dbuf then
ADreg <= '0' & (bufreg((2 * SIZE - 3) downto (SIZE - 1)) - dbuf((SIZE - 2) downto 0));
DVNDreg <= DVNDreg ((SIZE - 2) downto 0) & '1';
else
bufreg <= bufreg((2 * SIZE - 2) downto 0) & '0';
end if;
if count /= SIZE then
count <= count + 1;
else
count <= 0;
end if;
end case;
end if;
end if;
end process;
end behav;
And here is the code for the Verilog test fixture (.v file):
module BINdivisionTEST;
// Inputs
reg reset;
reg en;
reg clk;
reg [7:0] num ;
reg [7:0] den ;
// Outputs
wire [7:0] res;
wire [7:0] rm;
// Instantiate the Unit Under Test (UUT)
division uut (
.reset(reset),
.en(en),
.clk(clk),
.num(num),
.den(den),
.res(res),
.rm(rm)
);
initial begin
// Initialize Inputs
reset = 0;
en = 0;
clk = 0;
//num = 0;
//den = 0;
// Wait 100 ns for global reset to finish
#100;
en = 1;
#100;
clk=1;
num <= "00110011" ;
den <= "00010011" ;
// Add stimulus here
end
endmodule
My biggest problems seem to be initialization of the inputs and probably some mistaken assignments, misuse of the test fixture file and some bad coding.
I should also add that the divider code was compiled in vhdl, ISE 14.3.
I'm extremely sorry if this has been answered before and I don't mean to piss anyone off by uploading bad and amateur code. If this kind of problem has been addressed before could you please provide me with a link.
Again, any help is greatly appreciated.

The simulator may be treating those as strings instead of numbers. Try changing:
num <= "00110011" ;
den <= "00010011" ;
to:
num <= 8'b00110011;
den <= 8'b00010011;

I'm no expert on Verilog but it looks as if you might not be asserting Reset to your VHDL component before testing it.
That would lead "Count" in an uninitialised state so that when you use it, anything could happen and the "XXXX" outputs are a reflection of that.
The reset sequence should look like
En <= '0';
Clk <= '0';
Reset <= '1';
wait for 100 ns;
Reset <= '0';
wait for 100 ns;
-- start testing here
(in VHDL of course ... but it'll translate to Verilog easily)

Related

PISO register output is not as expected

I have a problem in PISO verilog register.
Below is my code
`timescale 1ns / 1ps
module PISO(
input clk,
input load,
input [3:0] d,
output reg Qout);
reg [3 : 0]Q;
always # (posedge clk)
begin
if ( load )
Q <= d;
else
begin
Qout <= d[3];
Q<= { Q[2:0] , 1'b0 };
end
end
endmodule
and my testbench
`timescale 1ns / 1ps
module PISO_tb();
PISO uut(clk,load,d,Qout);
reg clk;
reg load;
reg [3:0]d;
wire Qout;
initial begin
clk=0;
forever #5 clk = ~clk;
end
initial begin
load = 1;
d[0] = 1'b0;
d[1] = 1'b1;
d[2] = 1'b0;
d[3] = 1'b1;
#6 load = 0;
end
endmodule
And it isn't working as it should, please help me with testbench maybe? Because I think the verilog code is okay and it should work properly.
You want the Qout signal to be the output of the shift register (Q) instead of the input, so that the output toggles instead of remaining at 1. Change:
Qout <= d[3];
to:
Qout <= Q[3];

VHDL, process not updating variable's value, implementing a Merge Sort

I am trying to implement an example of Merge Sort algorithm on VHDL in order to sort 4 128bit numbers.
I am using sequential code. I have a process on which I make comparisons. The process consists of 3 phases which implement the logic behind Merge Sort.
The problem is that I am using a variable count : integer which counts clock cycles. I want the phases to follow clock cycles.
It seems like the simulation enters the first IF statement (of Phase 1) but does not enter the others so I guess count variable does not update its value.
I have tried several changes but seems like I am missing something here.
I know the post is a little big, I would appreciate any help! Thanks!
entity Merge_Sort is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
en : in STD_LOGIC;
In_a : in STD_LOGIC_VECTOR(15 downto 0 ) ;
In_b : in STD_LOGIC_VECTOR(15 downto 0 ) ;
In_c : in STD_LOGIC_VECTOR(15 downto 0 ) ;
In_d : in STD_LOGIC_VECTOR(15 downto 0 ) ;
Sorted_a : out STD_LOGIC_VECTOR(15 downto 0 ) ;
Sorted_b : out STD_LOGIC_VECTOR(15 downto 0 ) ;
Sorted_c : out STD_LOGIC_VECTOR(15 downto 0 ) ;
Sorted_d : out STD_LOGIC_VECTOR(15 downto 0 ) );
end Merge_Sort;
architecture Behavioral of Merge_Sort is
signal temp1a,temp1b,temp1c,temp1d : STD_LOGIC_VECTOR(15 downto 0 ) ;
TYPE arr2 IS ARRAY (0 to 1 ) of STD_LOGIC_VECTOR(15 downto 0) ;
TYPE arr4 IS ARRAY (0 to 3 ) of STD_LOGIC_VECTOR(15 downto 0) ;
signal Array1 , Array2 : arr2 ;
signal mergedArr : arr4 ;
signal temp : std_logic_vector(15 downto 0 ) ;
begin
temp1a <= (others =>'0' ) WHEN reset ='1' else -- Asychronous Resetting
In_a ;
temp1b <= (others =>'0' ) WHEN reset ='1' else
In_b ;
temp1c <= (others =>'0' ) WHEN reset ='1' else -- Asychronous Resetting
In_c ;
temp1d <= (others =>'0' ) WHEN reset ='1' else
In_d ;
Sorted_a <= MergedArr(0) ;
Sorted_b <= MergedArr(1) ;
Sorted_c <= MergedArr(2) ;
Sorted_d <= MergedArr(3) ;
Sort: PROCESS(clk)
variable count : integer range 0 to 3 ;
BEGIN
if(reset ='1' ) then count := 0 ;
end if ;
IF ( clk'EVENT AND clk='1' ) then -- Conditions for process to run
IF (en ='1') then
IF(count =0) THEN -- Phase 1 of sort
if (temp1a<temp1b ) then Array1(0)<=temp1a ; Array1(1) <= temp1b ;
else Array1(1)<=temp1a ; Array1(0) <= temp1b ;
end if ;
if (temp1c<temp1d ) then Array2(0)<=temp1c ;Array2(1) <= temp1d ;
else Array2(1)<=temp1c ; Array2(0) <= temp1d ;
end if ;
count := count +1 ;
END IF ;
IF( count = 1) THEN -- Phase 2 of sort , computing min and max of array
if ( Array1(1) < Array2(1) ) then MergedArr(1) <= Array1(1) ; MergedArr(3) <= Array2(1) ;
else MergedArr(3) <= Array1(1) ; MergedArr(1) <= Array2(1) ;
end if ;
if ( Array1(0) < Array2(0) ) then MergedArr(0) <= Array1(0) ; MergedArr(2) <= Array2(0) ;
else MergedArr(2) <= Array1(0) ; MergedArr(0) <= Array2(0) ;
end if ;
count:= count +1 ;
END IF ;
IF(count =2 ) THEN -- Phase 3 of sort , FINAL
if ( MergedArr(1) > MergedArr(2) ) then
temp<= MergedArr(2 ) ;
MergedArr(2) <= MergedArr(1) ;
MergedArr(1) <= temp ;
end if ;
END IF ;
END IF;
END IF ;
END PROCESS ;
end Behavioral;
The variable count is updated immediately inside each IF condition. So, for example, inside the IF(count=0), it is incremented to 1. Then it reaches the IF(count=1) statement, which will of course already be true.
I think really all you need to do is change it to IF ... ELSIF statements:
IF(count =0) THEN -- Phase 1 of sort
...
ELSIF( count = 1) THEN -- Phase 2 of sort , computing min and max of array
...
ELSIF(count =2 ) THEN -- Phase 3 of sort , FINAL
and I think it will work exactly as you expect.

CLB adder structure in Xilinx Virtex and adder implementations in VHDL

1-) I am curious about how ISE synthesizer implements adders in Virtex. I mean what is the smallest adder block size in slices? I was searching Xilinx documentations and I came up with this Virtex-4 FPGA User Guide
On page 204 it says, "The arithmetic logic includes an XOR gate that allows a 2-bit full adder to be implemented within a slice.". But there should be carry lookahead implementation. Because critical path increases logarithmic with the input width.
2-) The other question is, I want to implement long signed vector in VHDL. To achieve higher operating frequencies I want to implement two stage pipelined adder. For example:
signal a, b, c: signed(63 downto 0);
conventional method
c <= a + b;
What I want to implement
signal c_hi : signed(31 downto 0);
signal c_lo : signed(32 downto 0);
process(clk)
begin
if rising_edge (clk) then
--1st stage
c_lo <= ('0' & a(31 downto 0)) + ('0' & b(31 downto 0));
c_hi <= a(63 downto 32) + b(63 downto 32);
--2nd stage
c(63 downto 32) <= c_hi(31 downto 0) + (to_signed(0,31) & c_lo(32 downto 32));
c(31 downto 0) <= c_lo(31 downto 0);
end if;
end process;
But that includes 2x32bit adder + 1x33bit adder. So, what I asking is how can I give the carry out bit of lower addition while summing higher bits?
3-) Is there a way to obtain carry out/overflow bit without increasing width by one.
That's a pipelined adder:
signal a : signed(63 downto 0);
signal b : signed(63 downto 0);
signal c : signed(64 downto 0);
signal sum_stage1 : unsigned(32 downto 0);
process(clk)
begin
if rising_edge(clk) then
-- stage 1: add first 32 bits
sum_stage1 <= ('0' & a(31 downto 0)) + ('0' & b(31 downto 0));
-- stage 2: add next 32 bits (incl. C_in)
c(31 downto 0) <= sum_stage1(31 downto 0); -- optional: align intermediate sums
c(64 downto 32) <= (32 downto 1 => '0') & sum_stage1(sum_stage1'high) +
('0' & a(63 downto 32)) +
('0' & b(63 downto 32));
end if;
end process;
Step 1: add 32 bits (31..0)
Step 2: add 32 bits (63..32) (incl. C_in; C_in = C_out from step 1)
Minimum resources consumption:
2x 32 bit adder or 32 + 33 bit adder if its signed and C_out is relevant
33 bit register

VHDL - Three layers of processes but no output from a logic unit in simulation

My lab partner and I can't figure out why we're not getting any output in our waveform simulation of this component. We simulated the component by itself and obtained the expected behavior, but nested inside the entity, the output signal was not being initialized and only had uninitialized 'X' response.
This is the component declaration in the top level entity:
99 component CH is
100 Port ( clk : in std_logic;
101 X : in std_logic_vector(31 downto 0);
102 Y : in std_logic_vector(31 downto 0);
103 Z : in std_logic_vector(31 downto 0);
104 CH_OUT : out std_logic_vector(31 downto 0)
105 );
106 end component;
This is the process we use to assign input/output:
289 round_compute2 : process (clk, CH_OUT_sig, e_sig, f_sig, g_sig, T1_sig)
290 begin
291 CH_X_in <= e_sig;
292 CH_Y_in <= f_sig;
293 CH_Z_in <= g_sig;
294 T1_sig <= std_logic_vector(unsigned(CH_OUT_sig));
295 end process;
This is the code for the CH component
1 library IEEE;
2 use IEEE.STD_LOGIC_1164.ALL;
3 use IEEE.STD_LOGIC_ARITH.ALL;
4 use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
6 -- CH is defined as (X AND Y) XOR (X' AND Z)
7 -- Verified working
8
9 entity CH is
10 Port ( clk : in std_logic;
11 X : in std_logic_vector(31 downto 0);
12 Y : in std_logic_vector(31 downto 0);
13 Z : in std_logic_vector(31 downto 0);
14 CH_OUT : out std_logic_vector(31 downto 0)
15 );
16 end CH;
17
18 architecture Behavioral of CH is
19
20 begin
21
22 Compute : process (clk, X, Y, Z)
23 begin
24
25 CH_OUT <= (X and Y) xor ((not X) and Z);
26
27 end process;
28
29 end Behavioral;
These questions are similar, but do not address the issue in this post because-
VHDL component and outputs based on generic
- Does not involve processes
Simple VHDL Problem with synchronous/asynchronous logic
- Does not involve components and signals that are assigned from the system to the component
Why doesn't my code produce output?
- Our code has the correct sensitivity list, I think
You should look through your tool's output for warnings. It sounds like you have an unbound component CH.
With:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- 3 use IEEE.STD_LOGIC_ARITH.ALL;
-- 4 use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- CH is defined as (X AND Y) XOR (X' AND Z)
-- Verified working
entity CH is
Port ( clk : in std_logic;
X : in std_logic_vector(31 downto 0);
Y : in std_logic_vector(31 downto 0);
Z : in std_logic_vector(31 downto 0);
CH_OUT : out std_logic_vector(31 downto 0)
);
end CH;
architecture Behavioral of CH is
begin
Compute : process (clk, X, Y, Z)
begin
CH_OUT <= (X and Y) xor ((not X) and Z);
end process;
end Behavioral;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ch_comp is
end entity;
architecture foo of ch_comp is
component CH is
Port ( clk : in std_logic;
X : in std_logic_vector(31 downto 0);
Y : in std_logic_vector(31 downto 0);
Z : in std_logic_vector(31 downto 0);
CH_OUT : out std_logic_vector(31 downto 0)
);
end component;
signal CH_X_in: std_logic_vector(31 downto 0);
signal CH_Y_in: std_logic_vector(31 downto 0);
signal CH_Z_in: std_logic_vector(31 downto 0);
signal CH_OUT_sig: std_logic_vector(31 downto 0);
signal e_sig: std_logic_vector(31 downto 0) := X"feedface";
signal f_sig: std_logic_vector(31 downto 0) := X"deadbeef";
signal g_sig: std_logic_vector(31 downto 0) := X"ffffffff";
signal T1_sig: std_logic_vector(31 downto 0);
signal clk: std_logic := '0';
begin
round_compute2 : process (clk, CH_OUT_sig, e_sig, f_sig, g_sig) --, T1_sig)
begin
CH_X_in <= e_sig;
CH_Y_in <= f_sig;
CH_Z_in <= g_sig;
T1_sig <= std_logic_vector(unsigned(CH_OUT_sig));
end process;
UUT:
CH
port map (
clk => clk,
X => CH_X_in,
Y => CH_Y_in,
Z => CH_Z_in,
CH_OUT => CH_OUT_sig
);
TEST:
process
begin
wait for 10 ns;
e_sig <= X"deadface";
f_sig <= X"facebeef";
g_sig <= X"EEEEFFFF";
wait for 10 ns;
wait;
end process;
end architecture;
I got:
Which is to say, it appears not to exhibit only uninitialized 'X's on CH_out_sig or T1_sig.
And it would appear you haven't revealed either enough or your VHDL design description or enough of the tool build and simulation process for a third party to see where you went wrong.

VHDL state machine outputs not in sync

This a general FPGA design question, I'm kind of new to FPGA design and have just embarked on my first large scale project, building some nice linear algebra solvers. The systems are pretty large so getting it right first time is important.
After successful simulations I am now sythensizing, but am having a nightmare, I am having to build and test it component by component as nothing behaves as it does in simulation! I'm mainly having issues with state machines where outputs are not being synchronized for example this is a data loader i'm using:
entity TriDiag_Data_Scheduler is
generic( W : integer :=16;
AW : integer := 10 -- address width
);
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC; --attatched to data finished
d_ready : in STD_LOGIC;
din : in STD_LOGIC_VECTOR (W-1 downto 0);
wr_en : out STD_LOGIC_VECTOR (3 downto 0);
dout_a, dout_b, dout_c, dout_y : out STD_LOGIC_VECTOR (W-1 downto 0);
addr_out : out STD_LOGIC_VECTOR (AW-1 downto 0));
end TriDiag_Data_Scheduler;
architecture Behavioral of TriDiag_Data_Scheduler is
type state is (a,b,c,y);
signal state_pr, state_next : state := y;
signal addr_reg, addr_next : std_logic_vector(AW-1 downto 0) :=(others =>'1');
signal wr_en_next : std_logic_vector(3 downto 0);
--data buffer
signal d_buff, d_buff_a, d_buff_b, d_buff_c, d_buff_y : std_logic_vector (W-1 downto 0) :=(others =>'0');
signal d_buff_a_reg, d_buff_b_reg, d_buff_c_reg, d_buff_y_reg : std_logic_vector (W-1 downto 0) :=(others =>'0');
begin
process(clk,rst)
begin
if(clk'event and clk ='1') then
state_pr <= state_next;
d_buff_a <= d_buff_a_reg;
d_buff_b <= d_buff_b_reg;
d_buff_c <= d_buff_c_reg;
d_buff_y <= d_buff_y_reg;
addr_reg <= addr_next;
wr_en <= wr_en_next;
end if;
end process;
addr_out <= addr_reg;
dout_a <= d_buff_a;
dout_b <= d_buff_b;
dout_c <= d_buff_c;
dout_y <= d_buff_y;
--Data out logic
process(state_pr, d_buff_a, d_buff_b, d_buff_c, d_buff_y, d_buff)
begin
d_buff_a_reg <= d_buff_a;
d_buff_b_reg <= d_buff_b;
d_buff_c_reg <= d_buff_c;
d_buff_y_reg <= d_buff_y;
case state_pr is
when a => --move data to a reg
d_buff_a_reg <= d_buff;
when b => --move data to b reg
d_buff_b_reg <= d_buff;
when c => --move data to c reg
d_buff_c_reg <= d_buff;
when y =>
d_buff_y_reg <= d_buff;
end case;
end process;
--next state and addr logic
process(state_pr, d_ready, rst, din)
begin
state_next <= state_pr;
addr_next <= addr_reg;
wr_en_next <= (others => '0');
if(rst = '1') then
state_next <= a;
addr_next <= (others =>'1');
wr_en_next <= (others => '0');
elsif(d_ready = '1') then
--Read in the data to the buffer
d_buff <= din;
--next state logic
case state_pr is
when a => --move data to a reg
addr_next <= addr_reg + 1;
-- d_buff_a_reg <= din;
wr_en_next <= "0001";
state_next <= b;
when b => --move data to b reg
wr_en_next <= "0010";
-- d_buff_b_reg <= din;
state_next <= c;
when c => --move data to c reg
wr_en_next <= "0100";
-- d_buff_c_reg <= din;
state_next <= y;
when y =>
-- d_buff_y_reg <= din;
wr_en_next <= "1000";
state_next <= a;
end case;
end if;
end process;
end Behavioral;
Basically when data is received via a UART module its job is to then load into the correct memory (controlled by write_en signal). The issue is that in all my designs (this is revision 7) all addr_out, wr_en and the correct data are in syn, but in synthesis I keep finding that the addr and wr_en are not in syn with the data and reads half from the preceding and half from the previous state.
What design practices should I use so that my VHDL is more syntheziable friendly because at this rate I will have to re-write all my previous hard-work for each component!
Many thanks
Sam
Working design, the old design was suffering from skew between the d_ready signal asserted from another module and this modules clk. As such the changes where not being synced as first hoped. To fixed this I but in the d_tick_next signal which asserts a locally sync signal d_tick which allowed all the correct behavior. One lesson learnt (correct me if i'm wrong) is that you can't rely on supposed externally clocked signals (such as d_ready) to be in sync with the receiving modules clk.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
-- ////////////////////////////////////////////////////////////////////
--Takes in the linear stream of data and builds up the memory structure
--INPUT DATA MUST FOLLOW SEQUENCE [a b c] x = [y] (0 if a or c do not exist) rows 0 and N respectivly
--//////////////////////////////////////////////////////////////////////
entity TriDiag_Data_Scheduler is
generic( W : integer :=16;
AW : integer := 10 -- address width
);
Port ( clk : in STD_LOGIC;
rst : in STD_LOGIC; --attatched to data finished
d_ready : in STD_LOGIC;
din : in STD_LOGIC_VECTOR (W-1 downto 0);
wr_en : out STD_LOGIC_VECTOR (3 downto 0);
dout_a, dout_b, dout_c, dout_y : out STD_LOGIC_VECTOR (W-1 downto 0);
addr_out : out STD_LOGIC_VECTOR (AW-1 downto 0));
end TriDiag_Data_Scheduler;
architecture Behavioral of TriDiag_Data_Scheduler is
type state is (a,b,c,y);
signal state_pr, state_next : state := y;
signal addr_reg, addr_next : std_logic_vector(AW-1 downto 0) :=(others =>'1');
signal wr_en_next : std_logic_vector(3 downto 0);
signal d_tick, d_tick_next : std_logic;
--data buffer
signal d_buff, d_buff_a, d_buff_b, d_buff_c, d_buff_y : std_logic_vector (W-1 downto 0) :=(others =>'0');
signal d_buff_a_reg, d_buff_b_reg, d_buff_c_reg, d_buff_y_reg : std_logic_vector (W-1 downto 0) :=(others =>'0');
begin
process(clk,rst)
begin
if(clk'event and clk ='1') then
state_pr <= state_next;
d_buff_a <= d_buff_a_reg;
d_buff_b <= d_buff_b_reg;
d_buff_c <= d_buff_c_reg;
d_buff_y <= d_buff_y_reg;
d_tick <= d_tick_next;
addr_reg <= addr_next;
wr_en <= wr_en_next;
end if;
end process;
addr_out <= addr_reg;
dout_a <= d_buff_a;
dout_b <= d_buff_b;
dout_c <= d_buff_c;
dout_y <= d_buff_y;
--Data out logic
process(state_pr,d_tick,rst)
begin
d_buff_a_reg <= d_buff_a;
d_buff_b_reg <= d_buff_b;
d_buff_c_reg <= d_buff_c;
d_buff_y_reg <= d_buff_y;
wr_en_next <= (others => '0');
if(rst = '1') then
addr_next <= (others =>'1');
else
addr_next <= addr_reg;
end if;
if(d_tick = '1') then
case state_pr is
when a => --move data to a reg
d_buff_a_reg <= d_buff;
addr_next <= addr_reg + 1;
wr_en_next <= "0001";
when b => --move data to b reg
d_buff_b_reg <= d_buff;
wr_en_next <= "0010";
when c => --move data to c reg
d_buff_c_reg <= d_buff;
wr_en_next <= "0100";
when y =>
d_buff_y_reg <= d_buff;
wr_en_next <= "1000";
end case;
end if;
end process;
--next state and d_tick
process(state_pr, d_ready, rst, din)
begin
state_next <= state_pr;
d_tick_next <='0';
if(rst = '1') then
state_next <= y;
elsif(d_ready = '1') then
--Read in the data to the buffer
d_buff <= din;
-- set sync tick
d_tick_next <= '1';
--next state logic
case state_pr is
when a =>
state_next <= b;
when b =>
state_next <= c;
when c =>
state_next <= y;
when y =>
state_next <= a;
end case;
end if;
end process;
end Behavioral;