Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VHDL: Code for 4-bit register

Status
Not open for further replies.

InS0mN1aC

Newbie level 3
Joined
Mar 31, 2012
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,329
Hello everyone,

I am new to VHDL and I have to write behavioral vhdl code for a 4-bit register with parallel load, using a D-Flip Flop. Here is the D-FF code i have to use:
Code:
library IEEE;
use IEEE.std_logic_1164.all;

entity dff is
   port (d   : in std_logic;
      preset : in std_logic;
      clear  : in std_logic;
      clk    : in std_logic;
      q      : out std_logic);
end dff;

architecture bhv_dff of dff is
begin
   process(clk, clear, preset)
   begin
      if clear = '0' then 
      
         q <= '0';
      elsif preset = '1' then
         q <= '1';
      elsif clk'event and clk='1' then
         q <= d;
      end if;
   end process;
end bhv_dff;

Can you help me how to use this, in order to implement the register?

Thank you!!
 

Hello everyone,

I am new to VHDL and I have to write behavioral vhdl code for a 4-bit register with parallel load, using a D-Flip Flop. Here is the D-FF code i have to use:

Can you help me how to use this, in order to implement the register?

I'm guessing that your statement "Here is the D-FF code i have to use" is the important part of this assignment because without it, all you would need to do is take your code for the D flip flop and make a slight modification to something like this


Code VHDL - [expand]
1
2
3
4
5
6
7
8
process(clk)
begin
   if clk'event and clk='1' then
      if (Load = '1') then
         q <= d;
      end if;
   end if;
end process;



So on the premise that the assignment has to do with using existing components (which in general is a good thing to be doing) you would go about it in the following manner:

- Create four instances of your D flip flop
- Create logic for the 'D' input so that if 'Load' is not true then the flip flops hold their current state.

The first step is to find out how to instantiate an entity four times...you do it like this for your problem description. I'm assuming here that your parallel input signals to the flip flops are called 'D_sig(1 to 4); clock input is called 'Clk_sig' and the output is 'Q_sig(1 to 4). Signals can of course be renamed as you see fit.

Code VHDL - [expand]
1
2
3
4
Dff1 : entity work.dff port map (d => D_sig(1), preset => '0', clear => '0', clk => Clk_sig, q => Q_sig(1));
Dff2 : entity work.dff port map (d => D_sig(2), preset => '0', clear => '0', clk => Clk_sig, q => Q_sig(2));
Dff3 : entity work.dff port map (d => D_sig(3), preset => '0', clear => '0', clk => Clk_sig, q => Q_sig(3));
Dff4 : entity work.dff port map (d => D_sig(4), preset => '0', clear => '0', clk => Clk_sig, q => Q_sig(4));



Now think about the logic for the four 'D' inputs to the flip flops (i.e. the 'D_sig' signals). If load is true, you want to load in the new input values from the entity (assuming them to be 'D(1 to 4)'; if it is false then you don't want Q_sig to change. Consider the following and see if you think it does the trick:

Code VHDL - [expand]
1
D_sig1 <= D when (Load = '1') else Q_sig;



Kevin Jennings
 
I'm guessing that your statement "Here is the D-FF code i have to use" is the important part of this assignment because without it, all you would need to do is take your code for the D flip flop and make a slight modification to something like this


Code VHDL - [expand]
1
2
3
4
5
6
7
8
process(clk)
begin
   if clk'event and clk='1' then
      if (Load = '1') then
         q <= d;
      end if;
   end if;
end process;



So on the premise that the assignment has to do with using existing components (which in general is a good thing to be doing) you would go about it in the following manner:

- Create four instances of your D flip flop
- Create logic for the 'D' input so that if 'Load' is not true then the flip flops hold their current state.

The first step is to find out how to instantiate an entity four times...you do it like this for your problem description. I'm assuming here that your parallel input signals to the flip flops are called 'D_sig(1 to 4); clock input is called 'Clk_sig' and the output is 'Q_sig(1 to 4). Signals can of course be renamed as you see fit.

Code VHDL - [expand]
1
2
3
4
Dff1 : entity work.dff port map (d => D_sig(1), preset => '0', clear => '0', clk => Clk_sig, q => Q_sig(1));
Dff2 : entity work.dff port map (d => D_sig(2), preset => '0', clear => '0', clk => Clk_sig, q => Q_sig(2));
Dff3 : entity work.dff port map (d => D_sig(3), preset => '0', clear => '0', clk => Clk_sig, q => Q_sig(3));
Dff4 : entity work.dff port map (d => D_sig(4), preset => '0', clear => '0', clk => Clk_sig, q => Q_sig(4));



Now think about the logic for the four 'D' inputs to the flip flops (i.e. the 'D_sig' signals). If load is true, you want to load in the new input values from the entity (assuming them to be 'D(1 to 4)'; if it is false then you don't want Q_sig to change. Consider the following and see if you think it does the trick:

Code VHDL - [expand]
1
D_sig1 <= D when (Load = '1') else Q_sig;



Kevin Jennings


Thank you very much for your answer, you have been very helpfull! I have 3 questions however:

1.

Code VHDL - [expand]
1
D_sig1 <= D when (Load = '1') else Q_sig;



I suppose that D_sig1 is Q_sig and D is D_Sig right?

2. in the port mapping, you set 'clear' to 0, according to the D FF I've posted, if clear is '0', then the output 'q' is always '0'.

3. What happens in the case when, clock = '0', clear ='1', preset='0' and Load='0'? Modelsim, simulation gives me X in some of the signals of the output(Q_sig). I can provide you with a screenshot of the simulation if you want.

This is the code so far:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
library IEEE;
use IEEE.std_logic_1164.all;
use work.dff;
 
entity bitreg4 is
   port (Clk_sig: in std_logic;
      Load : in std_logic;
      --D : in std_logic_vector(1 to 4);
      D_sig : in std_logic_vector(1 to 4);
      Q_sig : out std_logic_vector(1 to 4));
      
end bitreg4;
 
architecture bhv of bitreg4 is
begin
Dff1 : entity work.dff port map (d => D_sig(1), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(1));
Dff2 : entity work.dff port map (d => D_sig(2), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(2));
Dff3 : entity work.dff port map (d => D_sig(3), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(3));
Dff4 : entity work.dff port map (d => D_sig(4), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(4));
 
process(Clk_sig,D_sig,Load)
begin
if Load = '1' then  
Q_sig <= D_sig;
 
 
end if;
end process;
end bhv;

 

I have 3 questions however:

1.

Code VHDL - [expand]
1
D_sig1 <= D when (Load = '1') else Q_sig;



I suppose that D_sig1 is Q_sig and D is D_Sig right?

No, 'D_sig1' is a typo, it should be 'D_sig' like this...

Code VHDL - [expand]
1
D_sig <= D when (Load = '1') else Q_sig;


I'm assuming an entity like this:

Code VHDL - [expand]
1
2
3
4
5
6
entity Loadable_Reg is
   port (d   : in std_logic_vector(1 to 4);
      clk    : in std_logic;
      load  : in std_logic;
      q      : out std_logic_vector(1 to 4));
end Loadable_Reg;



2. in the port mapping, you set 'clear' to 0, according to the D FF I've posted, if clear is '0', then the output 'q' is always '0'.
Then either
- 'clear' is not named very well. Usually if a signal is active low (i.e. a low logic level '0' means 'true') then you indicate as such in the name so that people (like me) looking quickly don't have to dig into the code to see what it does. The usual convention is for such a signal to have an '_n' suffix. One should be able to discern the function of a signal based on the port name in the entity. You shouldn't have to look at the architecture. Suppliers of parts will typically put an overbar in the name, but you can't do that in simple text file.
- Maybe 'clear' is not implemented as intended in dff. Perhaps the 'q' outputs should be cleared when 'clear = 1', not when it is 0.

3. What happens in the case when, clock = '0', clear ='1', preset='0' and Load='0'?
Well, since there is no rising edge on clock, you're not clearing or presetting the flops, so according to the logic inside dff, the output 'q' should maintain the current state whatever that is.

Modelsim, simulation gives me X in some of the signals of the output(Q_sig). I can provide you with a screenshot of the simulation if you want.
If there has been no rising edge or clear or preset then the outputs of the flops should be unknown. However, once one of those things does happen they should take on definite values.

This is the code so far:

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
library IEEE;
use IEEE.std_logic_1164.all;
use work.dff;
 
entity bitreg4 is
   port (Clk_sig: in std_logic;
      Load : in std_logic;
      --D : in std_logic_vector(1 to 4);
      D_sig : in std_logic_vector(1 to 4);
      Q_sig : out std_logic_vector(1 to 4));
      
end bitreg4;
 
architecture bhv of bitreg4 is
begin
Dff1 : entity work.dff port map (d => D_sig(1), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(1));
Dff2 : entity work.dff port map (d => D_sig(2), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(2));
Dff3 : entity work.dff port map (d => D_sig(3), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(3));
Dff4 : entity work.dff port map (d => D_sig(4), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(4));
 
process(Clk_sig,D_sig,Load)
begin
if Load = '1' then  
Q_sig <= D_sig;
 
 
end if;
end process;
end bhv;


Your process drives the bits in 'Q_sig'. But the four instances of 'dff' also drives these bits. So you have two things driving 'Q_sig' which will cause unknowns as well if the process and the flip flop don't happen to agree on what they are driving. For example, if the process is trying to set Q_sig(1) to a value of '1', but 'dff' is trying to set it to '0', then the result is an 'X'. If 'dff' happened to want to also drive the bit to '0', then the result would be '0'. The correction needed is to use the typo corrected statement from my first post (however read my sidebar on multiple drivers before fixing).

Code VHDL - [expand]
1
D_sig <= D when (Load = '1') else Q_sig;


The 'D' input to the flip flop 'dff', must be muxed to provide the proper input to dff. If 'Load' is not true, you don't want to change the value of 'Q', which means you must take the 'Q' output of 'dff' and loop it back to the 'D' input of 'dff'. This is exactly what the statement above does. This means that you need to change your bitreg4 entity to have an input 'D' (which you had but commented out).

One other comment on the entity you posted: you have 'Q_sig : out std_logic_vector(1 to 4));' but since 'Q_sig' is used internally in the entity it is not strictly an output. You have a couple of choices for fixing:
- Change 'Q_sig' from type 'out' to type 'buffer'
- Make the entity output 'Q' rather than 'Q_sig' (as you originally probably had) and add a statement 'Q <= Q_sig;'. This statement then connects the 'Q_sig' outputs from the 'dff' to the output of your bitreg4 entity.

Sidebar on multiple drivers:
An easier way to catch multiple drivers on signals that are only supposed to be driven from one place is to use type std_ulogic rather than std_logic; std_ulogic_vector rather than std_logic_vector. The compiler will flag the error, you won't have to debug to find that the problem is that there are two drivers. In this instance, I would suggest that before you make the change for 'D_sig1 <= ...' that you change all of the 'std_logic*' to 'std_ulogic*', compile and see the error. THEN make the change for 'D_sig1 <= ...' and see that the compiler is happy again. No debug necessary.

If you are forced to use std_logic rather than std_ulogic, then get used to the Modelsim command 'drivers'. This command will list all of the things that are driving a given signal and tell you how they are attempting to drive them as well as the end result.

[soapbox on]Type std_logic gets drilled into everybody's head that it is the proper choice for logic signals...and it's not. The proper type for any signal that only has one driver (which is most signals by the way) is std_ulogic. The type checking system of VHDL and the std_logic_1164 package create this simple way to correctly create a design and have the compiler catch this simple (but common) type of mistake, but boneheads continue the practice of preaching that std_logic is the right choice. It's not, it never has been and never will be. But that's OK, I don't spend time debugging to find multiple drivers on a signal that is intended to have only one...everyone else can if they want to, it's their time to waste.[soapbox off]

Kevin Jennings
 
Hello everyone,

I am new to VHDL and I have to write behavioral vhdl code for a 4-bit register with parallel load, using a D-Flip Flop. Here is the D-FF code i have to use:
Code:
library IEEE;
use IEEE.std_logic_1164.all;

entity dff is
   port (d   : in std_logic;
      preset : in std_logic;
      clear  : in std_logic;
      clk    : in std_logic;
      q      : out std_logic);
end dff;

architecture bhv_dff of dff is
begin
   process(clk, clear, preset)
   begin
      if clear = '0' then 
      
         q <= '0';
      elsif preset = '1' then
         q <= '1';
      elsif clk'event and clk='1' then
         q <= d;
      end if;
   end process;
end bhv_dff;

Can you help me how to use this, in order to implement the register?

Thank you!!

You're code implies you want an asynchronous PRESET and CLEAR_F, is this true? Will your "parallel load" signal be synchronous to the CLK or asynchronous, i.e. PRESET?

I rewrote your code: You'll need to take a closer look at your homework assignment and figure out what to do next.


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
library IEEE;
use IEEE.std_logic_1164.all;
 
entity dff is
   port (
        CLK     : in std_logic;
        CLEAR_F : in std_logic;
        PRESET  : in std_logic;
        D       : in std_logic(3 downto 0);  -- 4-bit DFF
        Q       : out std_logic(3 downto 0)  -- 4-bit DFF
    );
end dff;
 
architecture behav of dff is
begin
    process(CLK, CLEAR_F, PRESET)
    begin
        if CLEAR_F = '0' then -- asynchronous CLEAR_F
        Q <= "0000";
        else
            if PRESET = '1' then -- aysnchronous PRESET
                Q <= "1111";
            else
                if CLK'event and CLK = '1' then -- sample on rising edge of CLK
                                        -- add parallel load enable here if necessary.
                    Q <= D;
                end if; 
            end if;
        end if;
   end process;
end behav;

 
Thank you very much Kevin Jennings, I think I understand now how it works, and the simulation is running smoothly, according to the vhdl code :)
@BlackHelicopter: Yes, clear and preset are asynchronous, and the parallel load is synchronous i suppose, the assignment does not specify it.

These are the 2 implementations I made thanks to you:

1)

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
library IEEE;
use IEEE.std_logic_1164.all;
use work.dff;
 
entity bitreg4 is
   port (Clk_sig: in std_ulogic;
      Load : in std_ulogic;
      D : in std_ulogic_vector(1 to 4);
      D_sig : buffer std_ulogic_vector(1 to 4);
      Q_sig : buffer std_ulogic_vector(1 to 4));
      
end bitreg4;
 
architecture bhv of bitreg4 is
begin
Dff1 : entity work.dff port map (d => D_sig(1), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(1));
Dff2 : entity work.dff port map (d => D_sig(2), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(2));
Dff3 : entity work.dff port map (d => D_sig(3), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(3));
Dff4 : entity work.dff port map (d => D_sig(4), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(4));
 
D_sig <= D when (Load = '1') else Q_sig;
end bhv;



2)

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
library IEEE;
use IEEE.std_logic_1164.all;
 
entity bitreg4_2 is
   port (
        CLK     : in std_logic;
        CLEAR_F : in std_logic;
        PRESET  : in std_logic;
        D       : in std_logic_vector(3 downto 0);  -- 4-bit DFF
        Q       : out std_logic_vector(3 downto 0);  -- 4-bit DFF
        Load    : in std_logic
    );
end bitreg4_2;
 
architecture behav of bitreg4_2 is
begin
    process(CLK, CLEAR_F, PRESET)
    begin
        if CLEAR_F = '0' then -- asynchronous CLEAR_F
        Q <= "0000";
        elsif PRESET = '1' then -- aysnchronous PRESET
                Q <= "1111";
        else
                if CLK'event and CLK = '1' then -- sample on rising edge of CLK
                     if Load = '1' then                    -- add parallel load enable here if necessary.
                 Q <=D;
                end if; 
            end if;
        end if;
   end process;
end behav;

 

You said the assignment was "I have to write behavioral vhdl code for a 4-bit register with parallel load, using a D-Flip Flop. Here is the D-FF code i have to use"

Your bitreg4_2 doesn't use the dff code that you said you had to use. Also, a 4 bit register does not need to have resets and presets...the version I posted in my first post accomplishes the 4 bit register directly and then goes on to show how to do it by instantiating dff.

Glad to hear that it is all working.

Kevin
 

Yeah, I know it doesn't use the dff as a component, it's just a second way by modifying the dff code as you and BlackHelicopter suggested.

Thx again :)
 

Thank you very much Kevin Jennings, I think I understand now how it works, and the simulation is running smoothly, according to the vhdl code :)
@BlackHelicopter: Yes, clear and preset are asynchronous, and the parallel load is synchronous i suppose, the assignment does not specify it.

These are the 2 implementations I made thanks to you:

1)

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
library IEEE;
use IEEE.std_logic_1164.all;
use work.dff;
 
entity bitreg4 is
   port (Clk_sig: in std_ulogic;
      Load : in std_ulogic;
      D : in std_ulogic_vector(1 to 4);
      D_sig : buffer std_ulogic_vector(1 to 4);
      Q_sig : buffer std_ulogic_vector(1 to 4));
      
end bitreg4;
 
architecture bhv of bitreg4 is
begin
Dff1 : entity work.dff port map (d => D_sig(1), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(1));
Dff2 : entity work.dff port map (d => D_sig(2), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(2));
Dff3 : entity work.dff port map (d => D_sig(3), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(3));
Dff4 : entity work.dff port map (d => D_sig(4), preset => '0', clear => '1', clk => Clk_sig,q => Q_sig(4));
 
D_sig <= D when (Load = '1') else Q_sig;
end bhv;



2)

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
library IEEE;
use IEEE.std_logic_1164.all;
 
entity bitreg4_2 is
   port (
        CLK     : in std_logic;
        CLEAR_F : in std_logic;
        PRESET  : in std_logic;
        D       : in std_logic_vector(3 downto 0);  -- 4-bit DFF
        Q       : out std_logic_vector(3 downto 0);  -- 4-bit DFF
        Load    : in std_logic
    );
end bitreg4_2;
 
architecture behav of bitreg4_2 is
begin
    process(CLK, CLEAR_F, PRESET)
    begin
        if CLEAR_F = '0' then -- asynchronous CLEAR_F
        Q <= "0000";
        elsif PRESET = '1' then -- aysnchronous PRESET
                Q <= "1111";
        else
                if CLK'event and CLK = '1' then -- sample on rising edge of CLK
                     if Load = '1' then                    -- add parallel load enable here if necessary.
                 Q <=D;
                end if; 
            end if;
        end if;
   end process;
end behav;


That should do the trick. Typically the load enable is synchronous to the clk and the reset (or clear_f in this case) is asynchronous, like you have. That should be fine.

Manually instantiating the 4 DFF's like your first example is another way to do it as well, that approach however is more structural than behavioral. Both methods should come up with similar synthesis results.
 
Last edited:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top