M
Martijn van Pottelberghe
Guest
Hello everybody,
I'm trying to make a vhdl implementation of an 74162 (bcd counter with load)
Defined an entity and architecture, and entered a behavioural description
that I think should be ok overall.
After this definition, I made a testbench vhdl-file in order to simulate the
thing using modelsim.
Because i'm not even sure if the conflict appears within the testbench, or
in the component description, I'll insert both heir vhdl files below.
In order not to bother you too much I commented extensively so at least my
reasonings should be easy to follow.
Also I have a nice small png file of simulated signals, but the news server
won't let me post those 13kb..
Thanks for your attention so far..
Help would be greatly appreciated.
Regards,
Martijn
Here comes the 74162:
=====================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity sn_74162 is
port (
clr : in std_logic;
load : in std_logic;
ent : in std_logic;
enp : in std_logic;
clk : in std_logic;
a : in std_logic;
b : in std_logic;
c : in std_logic;
d : in std_logic;
oa : out std_logic;
ob : out std_logic;
oc : out std_logic;
od : out std_logic;
rco : out std_logic;
reset : in std_logic -- not an 74162's pin, though useful for testing
purposes
);
end sn_74162;
architecture gedrag of sn_74162 is
signal num_out: std_logic_vector(3 downto 0);
signal rco_on: std_logic; -- when i want to change rco, in fact i write to
rco_on
-- i do this in order to have a readable version of rco
begin
oa <= num_out(0);
ob <= num_out(1); -- map num_out vector to right outputs
oc <= num_out(2);
od <= num_out(3);
rco <= rco_on when rco_on'event;
process(reset) begin
if reset = '1' then
num_out <= "0000";
rco_on <= '0';
end if;
end process;
process(clk)
begin
if clk'event and clk='1' then -- clear, load all synchronous in the 162
-- if ripple carry has been set, now is the time to set it back to 0
-- (ripple carry is held high for 1 full clock cycle in this manner)
if rco_on = '1' then
rco_on <= '0';
end if;
if clr = '0' then -- logical diagram points out that clear has
presedence over load
num_out <= "0000";
elsif load = '0' then -- load has presedence over counting (loaded values
don'tget incremented)
num_out <= (a,b,c,d);
elsif enp = '0' and ent = '0' then -- increment
if num_out = "1001" then --is it 9, then back to 0 (because it's a bcd
counter)
num_out <= "0000";
rco_on <= '1'; -- clock to next counter in cascade
else num_out <= std_logic_vector(unsigned(num_out)+1);
end if;
end if;
end if; -- clk'event
end process;
end gedrag;
Here the testbench:
=======================================================================
library ieee;
use ieee.std_logic_1164.all;
entity testbench is
end testbench;
architecture tb_sn_74162 of testbench is
component sn_74162 port (
clr : in std_logic;
load : in std_logic;
ent : in std_logic;
enp : in std_logic;
clk : in std_logic;
a : in std_logic;
b : in std_logic;
c : in std_logic;
d : in std_logic;
oa : out std_logic;
ob : out std_logic;
oc : out std_logic;
od : out std_logic;
rco : out std_logic;
reset : in std_logic
); end component;
for uut : sn_74162 use entity work.sn_74162(gedrag);
signal clr : std_logic;
signal load : std_logic;
signal ent : std_logic;
signal enp : std_logic;
signal clk : std_logic := '0';
signal a : std_logic;
signal b : std_logic;
signal c : std_logic;
signal d : std_logic;
signal oa : std_logic;
signal ob : std_logic;
signal oc : std_logic;
signal od : std_logic;
signal rco : std_logic;
signal reset : std_logic;
constant HALF_CLOCK_PERIOD : time := 10 ns;
constant RESET_PERIOD : time := 2 ns;
--
-- place your own declarations here
--
begin --testbench
uut : sn_74162 port map (
clr => clr,
load => load,
ent => ent,
enp => enp,
clk => clk,
a => a,
b => b,
c => c,
d => d,
oa => oa,
ob => ob,
oc => oc,
od => od,
rco => rco,
reset => reset
);
clk <= not clk after HALF_CLOCK_PERIOD;
reset <= '1', '0' after RESET_PERIOD;
process
begin
-- test loading:
clr <= '1';
load <= '0';
ent <='0'; --load should have presedence; clock enable should'nt matter
enp <='0';
-- zeroes only
a <= '0';
b <= '0';
c <= '0';
d <= '0';
wait for 6*HALF_CLOCK_PERIOD;
-- ones only
a <= '1';
b <= '1';
c <= '1';
d <= '1';
wait for 6*HALF_CLOCK_PERIOD;
-- mixed
a <= '1';
b <= '0';
c <= '1';
d <= '0';
wait for 6*HALF_CLOCK_PERIOD;
-- value now 5
-- now test counting. enable is still active
load <='1'; -- load off; counting starts
wait for 24*HALF_CLOCK_PERIOD;
-- expected value now 5 + 16/2 (mod 10) = 4
-- (check if a pulse has been given to rco)
-- test inhibit:
ent <= '1'; -- one inhibit actief
wait for 6*HALF_CLOCK_PERIOD;
enp <= '1'; -- two inhibit actief
wait for 6*HALF_CLOCK_PERIOD;
-- test if load en clr still work (as they should)
a <= '1';
b <= '0';
c <= '1';
d <= '0';
wait for 6*HALF_CLOCK_PERIOD;
clr <= '0';
wait for 6*HALF_CLOCK_PERIOD;
wait;
end process;
end tb_sn_74162;
I'm trying to make a vhdl implementation of an 74162 (bcd counter with load)
Defined an entity and architecture, and entered a behavioural description
that I think should be ok overall.
After this definition, I made a testbench vhdl-file in order to simulate the
thing using modelsim.
Because i'm not even sure if the conflict appears within the testbench, or
in the component description, I'll insert both heir vhdl files below.
In order not to bother you too much I commented extensively so at least my
reasonings should be easy to follow.
Also I have a nice small png file of simulated signals, but the news server
won't let me post those 13kb..
Thanks for your attention so far..
Help would be greatly appreciated.
Regards,
Martijn
Here comes the 74162:
=====================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity sn_74162 is
port (
clr : in std_logic;
load : in std_logic;
ent : in std_logic;
enp : in std_logic;
clk : in std_logic;
a : in std_logic;
b : in std_logic;
c : in std_logic;
d : in std_logic;
oa : out std_logic;
ob : out std_logic;
oc : out std_logic;
od : out std_logic;
rco : out std_logic;
reset : in std_logic -- not an 74162's pin, though useful for testing
purposes
);
end sn_74162;
architecture gedrag of sn_74162 is
signal num_out: std_logic_vector(3 downto 0);
signal rco_on: std_logic; -- when i want to change rco, in fact i write to
rco_on
-- i do this in order to have a readable version of rco
begin
oa <= num_out(0);
ob <= num_out(1); -- map num_out vector to right outputs
oc <= num_out(2);
od <= num_out(3);
rco <= rco_on when rco_on'event;
process(reset) begin
if reset = '1' then
num_out <= "0000";
rco_on <= '0';
end if;
end process;
process(clk)
begin
if clk'event and clk='1' then -- clear, load all synchronous in the 162
-- if ripple carry has been set, now is the time to set it back to 0
-- (ripple carry is held high for 1 full clock cycle in this manner)
if rco_on = '1' then
rco_on <= '0';
end if;
if clr = '0' then -- logical diagram points out that clear has
presedence over load
num_out <= "0000";
elsif load = '0' then -- load has presedence over counting (loaded values
don'tget incremented)
num_out <= (a,b,c,d);
elsif enp = '0' and ent = '0' then -- increment
if num_out = "1001" then --is it 9, then back to 0 (because it's a bcd
counter)
num_out <= "0000";
rco_on <= '1'; -- clock to next counter in cascade
else num_out <= std_logic_vector(unsigned(num_out)+1);
end if;
end if;
end if; -- clk'event
end process;
end gedrag;
Here the testbench:
=======================================================================
library ieee;
use ieee.std_logic_1164.all;
entity testbench is
end testbench;
architecture tb_sn_74162 of testbench is
component sn_74162 port (
clr : in std_logic;
load : in std_logic;
ent : in std_logic;
enp : in std_logic;
clk : in std_logic;
a : in std_logic;
b : in std_logic;
c : in std_logic;
d : in std_logic;
oa : out std_logic;
ob : out std_logic;
oc : out std_logic;
od : out std_logic;
rco : out std_logic;
reset : in std_logic
); end component;
for uut : sn_74162 use entity work.sn_74162(gedrag);
signal clr : std_logic;
signal load : std_logic;
signal ent : std_logic;
signal enp : std_logic;
signal clk : std_logic := '0';
signal a : std_logic;
signal b : std_logic;
signal c : std_logic;
signal d : std_logic;
signal oa : std_logic;
signal ob : std_logic;
signal oc : std_logic;
signal od : std_logic;
signal rco : std_logic;
signal reset : std_logic;
constant HALF_CLOCK_PERIOD : time := 10 ns;
constant RESET_PERIOD : time := 2 ns;
--
-- place your own declarations here
--
begin --testbench
uut : sn_74162 port map (
clr => clr,
load => load,
ent => ent,
enp => enp,
clk => clk,
a => a,
b => b,
c => c,
d => d,
oa => oa,
ob => ob,
oc => oc,
od => od,
rco => rco,
reset => reset
);
clk <= not clk after HALF_CLOCK_PERIOD;
reset <= '1', '0' after RESET_PERIOD;
process
begin
-- test loading:
clr <= '1';
load <= '0';
ent <='0'; --load should have presedence; clock enable should'nt matter
enp <='0';
-- zeroes only
a <= '0';
b <= '0';
c <= '0';
d <= '0';
wait for 6*HALF_CLOCK_PERIOD;
-- ones only
a <= '1';
b <= '1';
c <= '1';
d <= '1';
wait for 6*HALF_CLOCK_PERIOD;
-- mixed
a <= '1';
b <= '0';
c <= '1';
d <= '0';
wait for 6*HALF_CLOCK_PERIOD;
-- value now 5
-- now test counting. enable is still active
load <='1'; -- load off; counting starts
wait for 24*HALF_CLOCK_PERIOD;
-- expected value now 5 + 16/2 (mod 10) = 4
-- (check if a pulse has been given to rco)
-- test inhibit:
ent <= '1'; -- one inhibit actief
wait for 6*HALF_CLOCK_PERIOD;
enp <= '1'; -- two inhibit actief
wait for 6*HALF_CLOCK_PERIOD;
-- test if load en clr still work (as they should)
a <= '1';
b <= '0';
c <= '1';
d <= '0';
wait for 6*HALF_CLOCK_PERIOD;
clr <= '0';
wait for 6*HALF_CLOCK_PERIOD;
wait;
end process;
end tb_sn_74162;