Question: Hello, i need to transform this VHDL four bit counter into an eight bit counter. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.std_logic_signed.all; use IEEE.NUMERIC_STD.ALL; -- this
Hello, i need to transform this VHDL four bit counter into an eight bit counter.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_signed.all;
use IEEE.NUMERIC_STD.ALL; -- this library package defines the conversion functions
-- from std_logic_vector to integer TO_INTEGER(slv_sig)
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
-- Uncomment the following library declaration if instantiating
-- any Xilinx leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity FourBitBinaryCounter is
Port ( D_H : inout STD_LOGIC_VECTOR (3 downto 0) := "0000"; -- parallel data inputs for loading an initial value into counter
Q_H : inout STD_LOGIC_VECTOR (3 downto 0); -- parallel count output
Clk_H : in STD_LOGIC; -- establishes period of time between one count and the next
T_H : in STD_LOGIC; -- Carry-in from a previous counter stage
Cout_H : out STD_LOGIC; -- Carry-out indicates this counter is at its highest count and will overflow on the next count
P_H : in STD_LOGIC; -- Enable counter will increment or count when this enable signal is asserted
Ld_H : in STD_LOGIC; -- Load will allow the counter to load the D inputs into its Q count outputs on the next clock edge
Rst_L : in STD_LOGIC); -- Resets the counter to it's initial all zeros state (st_0), this change is synchronized
end FourBitBinaryCounter;
architecture TI_163 of FourBitBinaryCounter is
constant CLK_TO_Q_DELAY : time := 2 ns;
constant COMBINATIONAL_LOGIC_DELAY : time := 3 ns;
-- this type describes array of SLV
type outputArrayType_t is array (0 to 15) of STD_LOGIC_VECTOR (3 downto 0);
-- this type describes arrays of integers in the range of 0 to 15
type stateArrayType_t is array (0 to 15) of integer range 0 to 15 ;
signal stateToNextStateMap: stateArrayType_t := ( 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 0); -- after state zero nextState is 1, after 1 nextState is 2, etc..
-- Using the current state as the index into the above array, the value retrieved from that location is the NextState
signal stateToOutputMap: outputArrayType_t := ( "0101", "0001", "0010", "0011", -- here the first state will output a 5 and the last state will output a 6
"0100", "0000", "1111", "0111", -- notice how we swap the five with the zero, and the six with the 15
"1000", "1001", "1010", "1011",
"1100", "1101", "1110", "0110"
);
-- Using the current state as the index into the above array, the std_logic_vector retrieved from that location is value to be assigned to Q_H,
-- except in the case that the Ld_H signal is asserted
-----------------------------------------------------------------------------------------------------------------------------------
-- signal outputToStateMap: state_type := (9,1,2,3,4,0,15,7,8,5,10,11,12,13,14,6);
-- Using the current D_H std_logic_array value then converting it to an integer,
-- and using the integer as the index in to the above array, the value retrieved from that location is the state that will produce
-- that output, so that proposing that as the next state will assure to "load" the D_H value indirectly into that state.
-- this also means that the next state is being controlled by the normal state sequence but may also include jumps programmed by the
signal index, presentState, nextState : integer := 0; -- by declaring the presentState and the nextState as integer they could be used as an index into the arrays
-- initialize to zero to avoid out of bounds arrays access
signal internalOutput: std_logic_vector (3 downto 0);
begin -- begin of architecture block
-- this process models the state flip-flops behaviour
SYNC_PROC: process (Clk_H)
begin
if (CLK_H'event and CLK_H = '1') then -- detect rising edge of clock
if (Rst_L = '0') then
presentState <= 0 after CLK_TO_Q_DELAY;
else
presentState <= nextState after CLK_TO_Q_DELAY ;
if(nextState = 15) then
Cout_H <= '1' ;
end if;
-- Q_H <= internalOutput after CLK_TO_Q_DELAY;
end if;
end if;
end process;
--Mealy -type FSM outputs dependend on State and Inputs
NEXT_STATE_DECODER: process (presentState, T_H, P_H, Ld_H)
begin
--declare default state for next_state to avoid latches
nextState <= presentState; --default is to stay in current state
if ( (P_H = '1') and (T_H = '1') and (Ld_H = '0') )
then
nextState <= stateToNextStateMap(presentState) after COMBINATIONAL_LOGIC_DELAY;
elsif ( (Ld_H = '1') and ( Rst_L = '1') )
then
for index in 0 to 15 loop
if (stateToOutputMap(index) = D_H) then
nextState <= index;
end if;
end loop;
-- choose the nextState that will produce the desired state
end if;
end process;
OUTPUT_DECODER: process(presentState ) -- process(nextState) -- every time presentStateChanges, we can also use changes in nextState and then use registered internalOutputs that are loaded into the externalOutputs at clock edge transition
begin
-- internalOutput <= stateToOutputMap(nextState);
Q_H <= stateToOutputMap(presentState);
end process;
end TI_163;
--TestBench
library IEEE;
use IEEE.STD_LOGIC_1164.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 leaf cells in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity TB_FourBitBinaryCounter is
-- Port ( );
end TB_FourBitBinaryCounter;
architecture Behavioral of TB_FourBitBinaryCounter is
-- Declare Model Under Test (MUT)
component FourBitBinaryCounter is
Port ( D_H : inout STD_LOGIC_VECTOR (3 downto 0) := "0000"; -- parallel data inputs for loading an initial value into counter
Q_H : inout STD_LOGIC_VECTOR (3 downto 0); -- parallel count output
Clk_H : in STD_LOGIC; -- establishes period of time between one count and the next
T_H : in STD_LOGIC; -- Carry-in from a previous counter stage
Cout_H : out STD_LOGIC; -- Carry-out indicates this counter is at its highest count and will overflow on the next count
P_H : in STD_LOGIC; -- Enable counter will increment or count when this enable signal is asserted
Ld_H : in STD_LOGIC; -- Load will allow the counter to load the D inputs into its Q count outputs on the next clock edge
Rst_L : in STD_LOGIC); -- Resets the counter to it's initial all zeros state (st_0), this change is synchronized
end component;
-- declare wiring signals that will connect to the MUT
signal wD_H, wQ_H :std_logic_vector(3 downto 0);
signal wClk_H, wT_H, wCout_H, wP_H, wLd_H, wRst_L :std_logic;
constant CLOCK_PERIOD : time := 20 ns;
--
begin -- now define the operation or behavior of this test bench model
-- create an instance of the model under test
Counter_0: FourBitBinaryCounter port map (
D_H => wD_H,
Q_H => wQ_H,
Clk_H => wClk_H,
T_H => wT_H,
Cout_H => wCout_H,
P_H => wP_H,
Ld_H => wLd_H,
Rst_L => wRst_L
);
-- simulate clock
clockProcess: process(wClk_H)
begin
wClk_H <= NOT wClk_H after CLOCK_PERIOD/2;
end process;
-- apply stimulus to the MUT
stimulusProcess: process
begin
-- Test Case 0: Verify Reset Operation
wD_H <= "0000";
wT_H <= '1'; -- counter has carry-in asserted
wP_H <= '1'; -- counter has enabled asserted
wLd_H <= '0'; -- not loading yet
wRst_L <= '0' ; -- START COUNTER under RESET control
wait until ( wClk_H'event AND wClk_H = '0' ); -- synchronize to falling edge of clock
wait for 2*CLOCK_PERIOD; -- wait for 2clock periodswait 40 ns
-- verify that Q outputs are reset at "0000"
assert (wQ_H = "0000")
report " Counter failed to Reset under Rst_L signal"
severity FAILURE;
-- Test Case 1: Verify counter Loading Operation
wD_H <= "0101";
wT_H <= '1'; -- counter has carry-in asserted
wP_H <= '1'; -- counter has enabled asserted
wLd_H <= '1'; -- loading
wRst_L <= '1' ; -- Counter is NOT being Reset
wait for CLOCK_PERIOD; -- wait for 1 clock period
assert (wQ_H = "0101")
report " Counter failed to Load a new count"
severity FAILURE;
-- Test Case 2: Verify that counter can increment to 14,
-- when not loading or reset but it is enabled and has carry-in
wD_H <= "0000";
wT_H <= '1'; -- counter has carry-in asserted
wP_H <= '1'; -- counter has enabled asserted
wLd_H <= '0'; -- not loading
wRst_L <= '1' ; -- Counter is not being Reset
wait for 9*CLOCK_PERIOD; -- wait for 10 clock period
assert (wQ_H = "1110")
report " Counter failed to increment to 14"
severity FAILURE;
-- Test Case 3: Verify that counter can increment to 15,
-- when not loading or reset but it is enabled and has carry-in
-- and that counter generates a carry out.
wD_H <= "0000";
wT_H <= '1'; -- counter has carry-in asserted
wP_H <= '1'; -- counter has enabled asserted
wLd_H <= '0'; -- not loading
wRst_L <= '1' ; -- Counter is not being Reset
wait for CLOCK_PERIOD; -- wait for 1 clock period
assert (wQ_H = "1111") and (wCout_H = '1')
report " Counter failed to increment to 15 and generate carry out"
severity FAILURE;
-- Test Case 4: Verify that if the P_H enable signal is de-asserted the counter will not increment,
wD_H <= "0000";
wT_H <= '1'; -- counter has carry-in asserted
wP_H <= '0'; -- counter has enabled de-asserted. This will verify if the signal is de-asserted
wLd_H <= '0'; -- not loading
wRst_L <= '1' ; -- Counter is not being Reset
wait for CLOCK_PERIOD; -- wait for 1 clock period
assert (wQ_H = "1111") and (wCout_H = '1')
report " P_H failed, counter will not increment"
severity FAILURE;
-- Test Case 5: Verify that if the T_H enable signal is de-asserted the counter will not increment,
wD_H <= "0000";
wT_H <= '0'; -- counter has carry-in de-asserted. This will verify if the signal is de-asserted
wP_H <= '1'; -- counter has enabled asserted
wLd_H <= '0'; -- not loading
wRst_L <= '1' ; -- Counter is not being Reset
wait for CLOCK_PERIOD; -- wait for 1 clock period
assert (wQ_H = "1111") and (wCout_H = '1')
report " T_H failed, counter will not increment"
severity FAILURE;
end process;
end Behavioral;
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
