Question: Make Calendar Which Shows Month Number and Days of Month ?
Write Both in Combinational and Sequential VHDL Constructs ?
I am new on this VHDL and i have a quiz on Monday .. Anyone have any idea about where to start and how to start writing the programming in VHDL ?
Any help will be greatly appreciated ..
Thanks
Here is something to get you started with your assignment. It accepts the binary value of month, 1-12, and if it is a leap year or not, and outputs the number of days in that month. This is done without a clock (combinatorial/asynchronous logic).
I think you can take this and determine the best way to use sequential statements to create an alternative implementation based on what you assignment is asking for.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Days_In_Month is
port (
I_MONTH : in unsigned(3 downto 0);
I_LEAP_YEAR : in std_logic;
O_DAYS_IN_MONTH : out unsigned(4 downto 0)
);
end entity Days_In_Month;
architecture Days_In_Month_combinatorial of Days_In_Month is
signal month_30d : std_logic;
signal month_28d : std_logic;
signal month_31d : std_logic;
signal month_29d : std_logic;
begin
month_30d <= '1' when I_MONTH = 9 or
I_MONTH = 4 or
I_MONTH = 6 or
I_MONTH = 11
else '0';
month_28d <= '1' when I_MONTH = 2 and
I_LEAP_YEAR = '0'
else '0';
month_29d <= '1' when I_MONTH = 2 and
I_LEAP_YEAR = '1'
else '0';
month_31d <= '1' when month_30d = '0' and
month_28d = '0' and
month_29d = '0'
else '0';
O_DAYS_IN_MONTH <= to_unsigned(30,O_DAYS_IN_MONTH'length) when month_30d = '1' else
to_unsigned(28,O_DAYS_IN_MONTH'length) when month_28d = '1' else
to_unsigned(29,O_DAYS_IN_MONTH'length) when month_29d = '1' else
to_unsigned(31,O_DAYS_IN_MONTH'length) when month_31d = '1'
else to_unsigned(0,O_DAYS_IN_MONTH'length);
end architecture Days_In_Month_combinatorial;
Related
I am trying to retrieve data from an array of records constant. This is what i have in my current implementation:
CONSTANT Total_Feeds : INTEGER := 12;
TYPE Feed IS RECORD
s_Divisor : INTEGER RANGE 0 TO 255;
Display_Text : STRING(1 TO 8);
END RECORD Feed;
TYPE Feed_Array IS ARRAY (0 TO Total_Feeds -1) OF Feed;
CONSTANT FEED_INFO : Feed_Array := (
(225,"""0.02mm"""),
(112,"""0.04mm"""),
(75,"""0.06mm"""),
(56,"""0.08mm"""),
(45,"""0.10mm"""),
(38,"""0.12mm"""),
(32,"""0.14mm"""),
(28,"""0.16mm"""),
(25,"""0.18mm"""),
(23,"""0.20mm"""),
(20,"""0.22mm"""),
(19,"""0.24mm""")
);
------lower section of menu fsm----------
process(clk, reset)
begin
if (reset = '1') then
menu_pr <= start;
feed_index_pr <= 2;
ks_divisor_pr <= 0;
elsif (rising_edge(clk)) then
menu_pr <= menu_nx;
feed_index_pr <= feed_index_nx;
ks_divisor_pr <= ks_divisor_nx;
end if;
end process;
------upper section of menu fsm----------
process (menu_pr, menu_on_flag, delayed_select, delayed_up,
delayed_down, delayed_left, feed_index_pr, thread_index_pr,
delayed_right, menu_left_flag, menu_right_flag, menu_up_flag, menu_down_flag)
variable feedindex : integer range 0 to total_feeds;
begin
case menu_pr is
when start =>
feedindex := feed_index_pr;
feed_index_nx <= feedindex;
ks_divisor_nx <= FEED_INFO(feedindex).s_Divisor;
menu_nx <= feed_left;
when feed_left =>
feedindex := feed_index_pr;
feed_index_nx <= feedindex;
ks_divisor_nx <= FEED_INFO(feedindex).s_Divisor;
if (menu_on_flag = '1' and delayed_right = '1' and menu_right_flag = '1') then
menu_nx <= feed_left_right;
else
menu_nx <= feed_left;
end if;
when feed_left_right =>
feedindex := feed_index_pr + 1;
if (feedindex > (Total_Feeds - 1)) then
feedindex := 0;
feed_index_nx <= feedindex;
ks_divisor_nx <= FEED_INFO(feedindex).s_Divisor;
menu_nx <= feed_left;
else
feed_index_nx <= feedindex;
ks_divisor_nx <= FEED_INFO(feedindex).s_Divisor;
menu_nx <= feed_left;
end if;
end case;
end process;
rate_out <=ks_divisor_pr;
States are added after successful verification with simulation.
I'm trying to get the s_divisor for each record from a process using the following command:
ks_divisor_nx <= FEED_INFO(feedindex).s_Divisor;
Where feedindex changes from 0 to Total_Feeds -1, and ks_divisor is integer range 0 to 255.
Simulation results show correct output for all assignments except for the records with index 0, 1, and 2. Simulation output shows values: 11, 48, and 33 respectively.
simulation results
Any help is greatly appreciated.
Thanks.
Good time to everyone.
Resently I try to improve code in new project and found some interesting decoder.
It has 2 processes: in first all data formed and in second all bus triggered in out registers by control signal. But some wires need to be reset in some period of time (in second process).
So I deside to write this code for correct resettind some signals ([cm_regA/cm_regB] are records with different types of data):
----------------------------------------
LOAD_DATA_PROCESS: process(clk_i)
begin
if rising_edge(clk_i) then
if (reset_reg) then
cm_regB.reg_1 <= '0';
cm_regB.reg_2 <= '0';
cm_regB.reg_3 <= '0';
cm_regB.reg_4 <= '0';
else
if (load_reg) then
cm_regB <= cm_regA;
else null;
end if;
end if;
end if;
end process;
----------------------------------------
But this construction Synthesized with lot of multiplexers betwen reg_5...reg_10, so next code give me good synthesized construction and great speed:
----------------------------------------
LOAD_DATA_PROCESS: process(clk_i)
begin
if rising_edge(clk_i) then
if (reset_reg) then
cm_regB.reg_1 <= '0';
cm_regB.reg_2 <= '0';
cm_regB.reg_3 <= '0';
cm_regB.reg_4 <= '0';
else
if (load_reg) then
cm_regB.reg_1 <= cm_regA.reg_1;
cm_regB.reg_2 <= cm_regA.reg_2;
cm_regB.reg_3 <= cm_regA.reg_3;
cm_regB.reg_4 <= cm_regA.reg_4;
else null;
end if;
end if;
if (load_reg) then
cm_regB.reg_5 <= cm_regA.reg_5;
cm_regB.reg_6 <= cm_regA.reg_6;
cm_regB.reg_7 <= cm_regA.reg_7;
cm_regB.reg_8 <= cm_regA.reg_8;
cm_regB.reg_9 <= cm_regA.reg_9;
cm_regB.reg_10 <= cm_regA.reg_10;
else null;
end if;
end if;
end process;
----------------------------------------
So the questions next:
How make this construction more compact (like first example)?
Or how to make any changes in buses [cm_regA/cm_regB] visible for second example (in case changing first process and forgot add this changes to LOAD_DATA_PROCESS)?
P.S. Type of cm_regA and cm_regB are declarated in package. Here it is:
----------------------------------------
type cm_t is record
reg_1 : STD_LOGIC;
reg_2 : STD_LOGIC;
reg_3 : STD_LOGIC;
reg_4 : STD_LOGIC;
reg_5 : STD_LOGIC;
reg_6 : BOOLEAN;
reg_7 : STD_LOGIC;
reg_8 : STD_LOGIC;
reg_9 : STD_LOGIC_VECTOR(CONST_1-1 downto 0);
reg_10 : STD_LOGIC_VECTOR(CONST_2-1 downto 0);
end record cm_t;
----------------------------------------
In the case of your first code, you are indeed adding a dependency to reset for reg_5 to reg_10. This is because of the if-else statement. This is the effective code you write for these registers.
if not(reset_reg) and load_reg then
cm_regB.reg_5 <= cm_regA.reg_5;
[...]
cm_regB.reg_10 <= cm_regA.reg_10;
end if;
So, you should separate the reset block from the other assignment. You can achieve that by using the fact that for signals only the last assignment in a process will be applied the next delta cycle. So something like this:
LOAD_DATA_PROCESS: process(clk_i)
begin
if rising_edge(clk_i) then
if load_reg then
cm_regB <= cm_regA;
end if;
if reset_reg then
cm_regB.reg_1 <= '0';
cm_regB.reg_2 <= '0';
cm_regB.reg_3 <= '0';
cm_regB.reg_4 <= '0';
end if;
end if;
end process;
I have problems in creating a testbench for my test module that used package.
The package just contains a block of array which is accessed in different process.
-------------------- Package ---------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package my_array_pkg is
type my_array is array ( 0 to 9) of std_logic_vector(3 downto 0);
end my_array_pkg;
And the top entity.
----------------- TOP ENTITY -------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.my_array_pkg.all;
use IEEE.NUMERIC_STD.ALL;
entity pkt_top is
Port ( sys_clk : IN STD_LOGIC;
RESET : IN STD_LOGIC;
AN_EN : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
Seg_Cathodes : out Std_logic_Vector(6 downto 0)
);
end pkt_top;
architecture Behavioral of pkt_top is
SIGNAL CLK1HZ, CLK256HZ : STD_LOGIC;
signal my_digit : my_array;
COMPONENT Clock_1Hz is
Port ( Sys_clk : in STD_LOGIC;
Reset : in std_logic;
C_256Hz : out std_logic;
C_1Hz : out std_logic
);
end COMPONENT;
COMPONENT Array_Count is
Port ( C_1Hz : in std_logic;
reset : in std_logic;
digit : out my_array
);
end COMPONENT;
COMPONENT Display_Driver is
Port ( Reset : in std_logic;
c256Hz : in std_logic;
C_1Hz : in std_logic;
digit_in : in my_array;
Seg_Cathodes : out Std_logic_vector(6 downto 0);
An_En : out std_logic_vector(3 downto 0)
);
end COMPONENT;
begin
C1 : Clock_1Hz -- Gives two clock divisions.
PORT MAP ( SYS_CLK, RESET,CLK256HZ, CLK1HZ);
C2 : Array_Count -- Initialize array with some numbers on every 1Hz edge
PORT MAP ( CLK1HZ, RESET, my_digit);
C3 : Display_Driver -- Dispaly the numbers on seven segments with 256Hz switching time between segments.
PORT MAP (RESET , CLK256HZ, CLK1HZ, my_digit, SEG_CATHODES, AN_EN);
end Behavioral;
The code is synthesizable and works on BASYS2 board, However I cannot simulate it via a testbench.
--------------------My TestBench -------------------------
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use work.my_array_pkg.all;
ENTITY pkg_tb IS
END pkg_tb;
ARCHITECTURE behavior OF pkg_tb IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT pkt_top
PORT(
sys_clk : IN std_logic;
RESET : IN std_logic;
AN_EN : OUT std_logic_vector(3 downto 0);
array_test : INOUT my_array;
Seg_Cathodes : OUT std_logic_vector(6 downto 0)
);
END COMPONENT;
--Inputs
signal sys_clk : std_logic := '0';
signal RESET : std_logic := '0';
signal my_digit : my_array;
--Outputs
signal AN_EN : std_logic_vector(3 downto 0);
signal Seg_Cathodes : std_logic_vector(6 downto 0);
-- Clock period definitions
constant sys_clk_period : time := 20 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: pkt_top PORT MAP (
sys_clk => sys_clk,
RESET => RESET,
AN_EN => AN_EN,
array_test => my_digit,
Seg_Cathodes => Seg_Cathodes
);
-- Clock process definitions
sys_clk_process :process
begin
sys_clk <= '0';
wait for sys_clk_period/2;
sys_clk <= '1';
wait for sys_clk_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
-- hold reset state for 100 ns.
reset <= '1';
wait for 100 ns;
reset <= '0';
-- insert stimulus here
wait;
end process;
END;
---------------------------------------------------------------
When simulate the ISIM gives an error about the 'array_test' not being availabe in the Top entity, and if this is removed the simulation remains blank.
Any Help about the testbench please.
I can't see a port named "array_test"in the description of the entity pkt_top. You must declare it an an output port in pkt_top.
Another way to avoid errors in testbench is to delete the .vhd file of testbench and create a new one for the entity you want to simulate.
In addition to, every time you edit the port of your top entity, you can delete the old and create a new testbench or edit the component of the same entity in your testbench.
How to connect 8-bit GPIO "General-Purpose Input/Output" with 3 8-bit timers (Timer0, Timer1, PWM) as multiplexer.
GPIO get the 3 Timers outputs as an input, choose between them. It's output is one of the 3 inputs it had as a multiplexer?
How can I make this connection in design also in VHDL by coding?
What will be the functionality of each pin in GPIO?
Thanks.
*-- Assuming you have logic to produce the mux selects: mux_sel(1 downto 0) :*
C1: PROCESS (timer0, timer1, pwm, mux_sel) IS
BEGIN
CASE mux_sel IS
WHEN "00" => gpio_in <= timer0;
WHEN "01" => gpio_in <= timer1;
WHEN "10" => gpio_in <= pwm;
WHEN OTHERS => NULL;
END CASE;
END PROCESS C1;
-- Even simpler:
gpio_in <= timer0 WHEN mux_sel = "00" ELSE
timer1 WHEN mux_Sel = "01" ELSE
pwm;
I have this warnig in my code for a FSM:
WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: Lights<5>, U1/next_state_cmp_eq0000, next_state_int<0>, pres_state_int<0>.
WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: Lights<4>, next_state_int<1>, pres_state_int<1>.
WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: next_state_int<2>, U1/next_state_cmp_eq0003, Lights<3>, pres_state_int<2>.
WARNING:Xst:2170 - Unit P22_MustangSecuentialTailLight_Structural : the following signal(s) form a combinatorial loop: next_state_int<3>, pres_state_int<4>, U1/next_state_cmp_eq0013, pres_state_int<3>, Lights<2>, next_state_int<4>.
Its for a loop made in the code, the image of my diagram
But that enbedded signal(pres_state_int) is necessary for update the next state logic block. The code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.States.all;
entity P22_MustangSecuentialTailLight_Structural is
Port ( Lturn : in STD_LOGIC;
Rturn : in STD_LOGIC;
Hazard : in STD_LOGIC;
Rst : in STD_LOGIC;
Break : in STD_LOGIC;
Clk100MHz : in STD_LOGIC;
Lights : out STD_LOGIC_VECTOR (5 downto 0));
end P22_MustangSecuentialTailLight_Structural;
architecture Behavioral of P22_MustangSecuentialTailLight_Structural is
component NextStateLogic
port (
BLRH : in STD_LOGIC_VECTOR (3 downto 0);
pres_state : in STD_LOGIC_VECTOR (4 downto 0);
next_state : out STD_LOGIC_VECTOR (4 downto 0));
end component;
component CurrentStateRegister
port (
pres_state_b : out STD_LOGIC_VECTOR (4 downto 0);
next_state_b : in STD_LOGIC_VECTOR (4 downto 0);
Rst : in STD_LOGIC;
Clk : in STD_LOGIC );
end component;
component OutputLogic
port (
pres_state_c : in STD_LOGIC_VECTOR (4 downto 0);
Lights : out STD_LOGIC_VECTOR (5 downto 0));
end component;
component Clk1Hz
port (
Rst : in STD_LOGIC;
Clk_in : in STD_LOGIC;
Clk_out : out STD_LOGIC);
end component;
--Embedded signal declaration
signal LRH_int : STD_LOGIC_VECTOR (3 downto 0);
signal next_state_int : state_values := ST0;
signal pres_state_int : state_values := ST0;
signal Clk1Hz_int : STD_LOGIC;
begin
LRH_int <= Break & Lturn & Rturn & Hazard;
U1 : NextStateLogic
port map(
BLRH => LRH_int,
pres_state => pres_state_int,
next_state => next_state_int
);
U2 : CurrentStateRegister
port map(
pres_state_b => pres_state_int,
next_state_b => next_state_int,
Rst => Rst,
Clk => Clk1Hz_int
);
U3 : OutputLogic
port map(
pres_state_c => pres_state_int,
Lights => Lights
);
U4 : Clk1Hz
port map(
Rst => Rst,
Clk_in => Clk100MHz,
Clk_out => Clk1Hz_int
);
end Behavioral;
Next is the package use for encoding the code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
package States is
subtype state_values is std_logic_vector(4 downto 0);
constant ST0: state_values := "00000";
constant ST1: state_values := "00001";
constant ST2: state_values := "00010";
constant ST3: state_values := "00011";
constant ST4: state_values := "00100";
constant ST5: state_values := "00101";
constant ST6: state_values := "00110";
constant ST7: state_values := "00111";
constant ST8: state_values := "01000";
constant ST9: state_values := "01001";
constant ST10: state_values := "01010";
constant ST11: state_values := "01011";
constant ST12: state_values := "01100";
constant ST13: state_values := "01101";
constant ST14: state_values := "01110";
constant ST15: state_values := "01111";
constant ST16: state_values := "10000";
signal pres_state, next_state: state_values;
end States;
NextStateLogic component code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use work.States.all;
entity NextStateLogic is
Port( BLRH : in STD_LOGIC_VECTOR (3 downto 0);
pres_state : in STD_LOGIC_VECTOR (4 downto 0);
next_state : out STD_LOGIC_VECTOR (4 downto 0));
end NextStateLogic;
architecture NextStateLogicl of NextStateLogic is
begin
FSM: process (pres_state, BLRH)
begin
case pres_state is
when "00000" =>
case BLRH is
when "0000" => next_state <= "00000";--ST0; -- All off
when "0010" => next_state <= "00100";--ST4; -- Right Turn
when "0100" => next_state <= "00111";--ST7; -- Left Turn
when "0110" => next_state <= "00101";--ST5; -- All off
when others => next_state <= "00001";--ST1; -- Hazard
end case;
when "00001" => next_state <= "00010";--ST2;
when "00010" => next_state <= "00011";
when "00011" =>
case BLRH is
when "1000" => next_state <= "00011"; -- Break
when "1110" => next_state <= "00011"; --
when "1010" => next_state <= "01101"; -- Right Turn & Break
when "1100" => next_state <= "01010"; -- Left Turn & Break
when others => next_state <= "00000"; -- Hazard
end case;
when "00100" => next_state <= "00101";
when "00101" => next_state <= "00110";
when "00110" => next_state <= "00000";
when "00111" => next_state <= "01000";
when "01000" => next_state <= "01001";
when "01001" => next_state <= "01010";
when "01010" => next_state <= "01011";
when "01011" => next_state <= "01100";
when "01100" =>
case BLRH is
when "1100" => next_state <= "01111"; -- Right Turn & Break
when "1010" => next_state <= "10000"; -- Left Turn & Break
when others => next_state <= "00000";
end case;
when "01101" => next_state <= "01110";
when "01110" => next_state <= "01100";
when "01111" => next_state <= "01010";
when "10000" => next_state <= "01101";
-- Include when others to avoid latches
when others => next_state <= "00000";
end case;
end process FSM;
end NextStateLogicl;
CurrentStateRegister component code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity CurrentStateRegister is
Port(
pres_state_b : out STD_LOGIC_VECTOR (4 downto 0);
next_state_b : in STD_LOGIC_VECTOR (4 downto 0);
Rst : in STD_LOGIC;
Clk : in STD_LOGIC
);
end CurrentStateRegister;
architecture CurrentStateRegister of CurrentStateRegister is
begin
StateReg: process (Clk,Rst,next_state_b)
begin
if (Rst = '1') then
pres_state_b <= "00000";
elsif Clk = '1' then
pres_state_b <= next_state_b;
else
pres_state_b<= "00000";
end if;
end process StateReg;
end CurrentStateRegister;
OutputLogic component code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity OutputLogic is
Port(
pres_state_c : in STD_LOGIC_VECTOR (4 downto 0);
Lights : out STD_LOGIC_VECTOR (5 downto 0));
end OutputLogic;
architecture OutputLogic of OutputLogic is
begin
Outputs: process (pres_state_c)
begin
case pres_state_c is
when "00000" => Lights <= "000000";
----------------------------------------------- Hazard
when "00001" => Lights <= "001100";
when "00010" => Lights <= "011110";
when "00011" => Lights <= "111111";
----------------------------------------------- Right Turn
when "00100" => Lights <= "000100";
when "00101" => Lights <= "000110";
when "00110" => Lights <= "000111";
----------------------------------------------- Left Turn
when "00111" => Lights <= "001000";
when "01000" => Lights <= "011000";
when "01001" => Lights <= "111000";
----------------------------------------------- Right Turn & Break
when "01010" => Lights <= "001111";
when "01011" => Lights <= "011111";
-----------------------------------------------
when "01111" => Lights <= "000111";
when "01100" => Lights <= "111111"; -- Common Case
when "10000" => Lights <= "111000";
----------------------------------------------- Left Turn & Break
when "01101" => Lights <= "111100";
when "01110" => Lights <= "111110";
when others => Lights <= "000000";
end case;
end process Outputs;
end OutputLogic;
And finally the Clk1Hz component code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity Clk1Hz is
port (
Rst : in STD_LOGIC;
Clk_in : in STD_LOGIC;
Clk_out : out STD_LOGIC);
end Clk1Hz;
architecture Clk1Hz of Clk1Hz is
-- Definition of embedded signals and constants
-- Constants used for frequency division
constant Fosc : integer := 100000000; --Frecuencia del oscilador de tabletas NEXYS 3
constant Fdiv : integer := 5; --Frecuencia deseada del divisor
constant CtaMax : integer := Fosc / Fdiv; --Cuenta maxima a la que hay que llegar
-- Signal used by the frequency division process
signal Cont : integer range 0 to CtaMax;
begin
-- Frequency divider to obtain a 2Hz signal from
-- the 100 MHz board oscillator
FreqDiv: process (Rst, Clk_in)
begin
if Rst = '1' then
Cont <= 0;
elsif (rising_edge(Clk_in)) then
if Cont = CtaMax - 1 then
Cont <= 0;
Clk_out <= '1';
else
Cont <= Cont + 1;
Clk_out <= '0';
end if;
end if;
end process FreqDiv;
end Clk1Hz;
Iam missing something?? Is there another way to instanciate the component NextStateLogic?
Thanks:D
In CurrentStateRegister, you need to test for rising_edge(clk) instead of clk = '1'. Your current code infers a latch instead of a register, causing a loop whenever clk = '1'. Also, lose the final else in the ControlStateRegister module:
StateReg: process (Clk,Rst,next_state_b)
begin
if (Rst = '1') then
pres_state_b <= "00000";
elsif (rising_edge(Clk)) then
pres_state_b <= next_state_b;
end if;
end process StateReg;