d2squared91
Technical User
hi everyone!
I hope you had an awesome sunday ... I'm not very familiar with VHDL and I was hoping you guys could give me a little help ... I have to design a 16-bit fully-synchronous down counter which can load the data from 2 transparent register, i.e. latches, and I have to signal back the controller when the counter reaches 0 with the TC_L output. I believe I have manage to design the counter but I can't figure out how to deal with the borrow out bit, i.e. the counter has reached 0. I'll be enormously grateful for your any tips you VHDL gurus can give me.
here's the code
[tt]
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
ENTITY DCounter IS
GENERIC ( n : positive := 4 );
PORT(
CK_L : IN STD_LOGIC; -- System clock
INIT_L : IN STD_LOGIC; -- Asynchronous reset
Dn_H : IN STD_LOGIC_VECTOR (n-1 downto 0); -- Parallel data
LDRA_H : IN STD_LOGIC; -- Load RegA ctrl
LDRB_H : IN STD_LOGIC; -- Load RegB ctrl
SEL_H : IN STD_LOGIC; -- Register select ctrl
CEN_H : IN STD_LOGIC; -- Count enable
LDC_H : IN STD_LOGIC; -- Load counter
TC_L : OUT STD_LOGIC; -- Terminate count
Qn_H : OUT STD_LOGIC_VECTOR (n-1 downto 0) -- Counter state
);
END ENTITY DCounter;
ARCHITECTURE rtl OF DCounter IS
SIGNAL Qa : STD_LOGIC_VECTOR(Qn_H'range); -- Internal A bus
SIGNAL Qb : STD_LOGIC_VECTOR(Qn_H'range); -- Internal B bus
BEGIN
LDRegAB: PROCESS (Dn_H, LDRA_H, LDRB_H)
-- Internal signals
variable enbAint, enbBint, selint : X01;
variable dint : STD_LOGIC_VECTOR(Dn_H'range);
begin
enbAint := To_X01(LDRA_H);
enbBint := To_X01(LDRB_H);
Dint := To_UX01(Dn_H);
if enbAint = '1' then
Qa <= dint;
-- pragma translate_off
elsif enbAint = 'X' then
Qa <= dint xor ((Dn_H'range => 'X') and (Qa xor dint));
-- pragma translate_on
end if;
if enbBint = '1' then
Qb <= dint;
-- pragma translate_off
elsif enbBint = 'X' then
Qb <= dint xor ((Dn_H'range => 'X') and (Qb xor dint));
-- pragma translate_on
end if;
end PROCESS LDRegAB;
Dcount: PROCESS (INIT_L, CK_L)
-- Internal signals
variable qint : STD_LOGIC_VECTOR(Qn_H'range); -- Internal counter state
begin
if INIT_L = '0' then
qint := (others => '1');
elsif rising_edge(CK_L) then
if LDC_H = '1' then
if SEL_H = '0' then
qint := Qa;
elsif SEL_H = '1' then
qint := Qb;
end if;
else
qint := unsigned(qint) - CEN_H;
end if;
end if;
Qn_H <= qint;
end PROCESS Dcount;
END ARCHITECTURE rtl;
[/tt]
thank you ever so much!
I hope you had an awesome sunday ... I'm not very familiar with VHDL and I was hoping you guys could give me a little help ... I have to design a 16-bit fully-synchronous down counter which can load the data from 2 transparent register, i.e. latches, and I have to signal back the controller when the counter reaches 0 with the TC_L output. I believe I have manage to design the counter but I can't figure out how to deal with the borrow out bit, i.e. the counter has reached 0. I'll be enormously grateful for your any tips you VHDL gurus can give me.
here's the code
[tt]
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
ENTITY DCounter IS
GENERIC ( n : positive := 4 );
PORT(
CK_L : IN STD_LOGIC; -- System clock
INIT_L : IN STD_LOGIC; -- Asynchronous reset
Dn_H : IN STD_LOGIC_VECTOR (n-1 downto 0); -- Parallel data
LDRA_H : IN STD_LOGIC; -- Load RegA ctrl
LDRB_H : IN STD_LOGIC; -- Load RegB ctrl
SEL_H : IN STD_LOGIC; -- Register select ctrl
CEN_H : IN STD_LOGIC; -- Count enable
LDC_H : IN STD_LOGIC; -- Load counter
TC_L : OUT STD_LOGIC; -- Terminate count
Qn_H : OUT STD_LOGIC_VECTOR (n-1 downto 0) -- Counter state
);
END ENTITY DCounter;
ARCHITECTURE rtl OF DCounter IS
SIGNAL Qa : STD_LOGIC_VECTOR(Qn_H'range); -- Internal A bus
SIGNAL Qb : STD_LOGIC_VECTOR(Qn_H'range); -- Internal B bus
BEGIN
LDRegAB: PROCESS (Dn_H, LDRA_H, LDRB_H)
-- Internal signals
variable enbAint, enbBint, selint : X01;
variable dint : STD_LOGIC_VECTOR(Dn_H'range);
begin
enbAint := To_X01(LDRA_H);
enbBint := To_X01(LDRB_H);
Dint := To_UX01(Dn_H);
if enbAint = '1' then
Qa <= dint;
-- pragma translate_off
elsif enbAint = 'X' then
Qa <= dint xor ((Dn_H'range => 'X') and (Qa xor dint));
-- pragma translate_on
end if;
if enbBint = '1' then
Qb <= dint;
-- pragma translate_off
elsif enbBint = 'X' then
Qb <= dint xor ((Dn_H'range => 'X') and (Qb xor dint));
-- pragma translate_on
end if;
end PROCESS LDRegAB;
Dcount: PROCESS (INIT_L, CK_L)
-- Internal signals
variable qint : STD_LOGIC_VECTOR(Qn_H'range); -- Internal counter state
begin
if INIT_L = '0' then
qint := (others => '1');
elsif rising_edge(CK_L) then
if LDC_H = '1' then
if SEL_H = '0' then
qint := Qa;
elsif SEL_H = '1' then
qint := Qb;
end if;
else
qint := unsigned(qint) - CEN_H;
end if;
end if;
Qn_H <= qint;
end PROCESS Dcount;
END ARCHITECTURE rtl;
[/tt]
thank you ever so much!