Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17050 Discussions

Issues with making a pipeline register in VHDL

Altera_Forum
Honored Contributor II
11,717 Views

I am currently having an issue with making a pipeline register in VHDL. A pipeline register is simply a register that connects two portions of a CPU pipeline together. It is easier to explain in code then on text in terms of its functions, so here is the code.  

library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity IF_to_ID_registers is port ( fetched_instruction : in std_logic_vector(31 downto 0); clear: in std_logic; writeregister : in std_logic; send_zeros_instead : in std_logic; clk : in std_logic; output_instruction : out std_logic_vector(31 downto 0) ); end IF_to_ID_registers; architecture Behavioral of IF_to_ID_registers is signal instruction_register : std_logic_vector(31 downto 0); -- The internal register begin process(fetched_instruction, writeregister, clk, send_zeros_instead) begin if ( clk = '0' AND writeregister = '1') then instruction_register <= fetched_instruction; -- Write the value into the register end if; if (rising_edge(clk)) then if (send_zeros_instead = '1') then output_instruction <= (others => '0'); -- Output zeros instead else output_instruction <= instruction_register; -- Output the register end if; end if; if (clear = '1') then instruction_register <= (others => '0'); -- Clear the register end if; end process; end Behavioral;  

 

The issue I have with this code is that during compilation I get the following error messages. 

 

Warning (10492): VHDL Process Statement warning at PipelineRegisters.vhd(42): signal "clear" is read inside the Process Statement but isn't in the Process Statement's sensitivity list Warning (10631): VHDL Process Statement warning at PipelineRegisters.vhd(25): inferring latch(es) for signal or variable "instruction_register", which holds its previous value in one or more paths through the process Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled  

 

I am wondering what I did wrong. It seems like the issue stems from the instruction_register signal, but I cant tell what the issue is.
0 Kudos
43 Replies
Altera_Forum
Honored Contributor II
4,793 Views

To get rid of latches use clocked process for all your logic. 

process(clk) 

if rising_edge(clk) then 

do this 

do that 

etc 

end if; 

end process;
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

Hi, have you drawn schematic for that ? It will help you very much. 

 

VHDL needs a few rigor.  

I advice you to write two synchronous process which begin by process(clk) (no other signal in sensitivity list) 

* one for instruction_register 

* the other for output_instruction

 

90% of process are process(reset, clk). 

 

if ( clk = '0' AND writeregister = '1') then :eek: 

 

i use pipeline to reduce propagation time of a design, but it increases latencies. 

 

First draw schema 

Second, describe it in VHDL. VHDL is a desciption language. 

Good work !
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

Is there any way then how I can implement the asynchronous clear.

0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

Just add it before clk edge statement: 

process(reset,clk) 

if reset then 

... 

elsif rising_edge(clk) then 

... 

... 

end if; 

end process;
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

Ok I tried doing it somewhat and now I have this issue: 

Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10029): Constant driver at PipelineRegisters.vhd(51) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (10028): Can't resolve multiple constant drivers for net "instruction_register" at PipelineRegisters.vhd(45) Error (12152): Can't elaborate user hierarchy "IF_to_ID_registers:inst10" Error: Quartus II 32-bit Analysis & Synthesis was unsuccessful. 20 errors, 5 warnings Error: Peak virtual memory: 357 megabytes Error: Processing ended: Tue Jul 24 15:22:46 2012 Error: Elapsed time: 00:00:02 Error: Total CPU time (on all processors): 00:00:02  

 

My new code is: 

 

library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity IF_to_ID_registers is port ( fetched_instruction : in std_logic_vector(31 downto 0); clear: in std_logic; writeregister : in std_logic; send_zeros_instead : in std_logic; clk : in std_logic; output_instruction : out std_logic_vector(31 downto 0) ); end IF_to_ID_registers; architecture Behavioral of IF_to_ID_registers is signal instruction_register : std_logic_vector(31 downto 0); begin process(clk) begin if (rising_edge(clk)) then if (send_zeros_instead = '1') then output_instruction <= (others => '0'); else output_instruction <= instruction_register; end if; end if; end process; process(clear) begin if (clear = '1') then instruction_register <= (others => '0'); end if; end process; process(writeregister, fetched_instruction) begin if ( clk = '0') then if (writeregister = '1') then instruction_register <= fetched_instruction; end if; end if; end process; end Behavioral;
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

I believe your issue is that you have two processes trying to drive the instruction_register. Try making one process to both clear and write to the instruction_register.

0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

Indeed, you are not allowed to drive a node from more than one assignment. You can view a process as one assignment and you can assign within one process in several statements depending on logic that decides the drive sequence. But assigning to same node in two processes does not tell the compiler how is that drive going to take place.

0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

Ok, now I tried this: 

 

library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity IF_to_ID_registers is port ( fetched_instruction : in std_logic_vector(31 downto 0); clear: in std_logic; writeregister : in std_logic; send_zeros_instead : in std_logic; clk : in std_logic; output_instruction : out std_logic_vector(31 downto 0) ); end IF_to_ID_registers; architecture Behavioral of IF_to_ID_registers is signal instruction_register : std_logic_vector(31 downto 0); begin process(clk) begin if (rising_edge(clk)) then if (send_zeros_instead = '1') then output_instruction <= (others => '0'); else output_instruction <= instruction_register; end if; end if; end process; process(clear, writeregister, fetched_instruction) begin if (clear = '1') then instruction_register <= (others => '0'); end if; if ( clk = '0') then if (writeregister = '1') then instruction_register <= fetched_instruction; end if; end if; end process; end Behavioral;  

 

I got these warnings: 

 

Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled Warning (14025): LATCH primitive "IF_to_ID_registers:inst10|instruction_register" is permanently disabled  

 

Can somebody help me? I am already a few days back from this problem.
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

You still haven't implemented all your assignments on clock edge. 

Why do you have one clocked process for output_instruction but you left the poor instruction register in a latching process. Just push it up into the clocked process.
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

So everything has to be on one of the two clock edges?

0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

You only have one clock in your design and so one clock edge. It is up to you to write your assignments in one clocked process or more than one clocked process.  

 

Additionally you can if you want get the clear outside(above) the edge statement to create asynch. clear to to the clocked registers.
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

But how will the write be implemented then. It cant be clocked

0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

As far as I see you need just this: 

 

process(clear,clk) begin if clear = '1' then output_instruction <= (others => '0'); instruction_register <= (others => '0'); elsif rising_edge(clk) then if write_register = '1' then instruction_register <= fetched_instruction; output_instruction <= instruction_register; end if; end if; end process;The send zero is obsolete. If you need further latency adjustments then you can arrange for it.
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

I need the send zero to make a "pipeline bubble in some cases". Thanks for the code. I will try it now

0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

Thanks, it now works!

0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

 

--- Quote Start ---  

Thanks, it now works! 

--- Quote End ---  

 

 

I strongly recommend to you to observe the logic you just described in VHDL (respective your old code) with the RTL-Viewer. It's no fault to see/know what QII synthesizes from your descriptions. 

 

Just right-click on the instantiation of your entity in the project navigator and select locate in RTL-Viewer
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

I am not sure that Alegomaster understands very well what is VHDL. 

 

@Alegomaster : I recommand to read VHDL guidelines of Altera (see also in Quartus help), and on other good sites like Doulos.com 

You must get good basis else you will spend cubic hours to "correct" the code.
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

You are right, in terms of me being unknowledgeable in VHDL. But I found another issue. In the RTL viewer it shows that there are 2 registers. I will show you the code and the jpeg I got from the RTL viewer. I am wondering how I can remove the second register. 

 

Here is the code: 

 

library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity IF_to_ID_registers is port ( fetched_instruction : in std_logic_vector(31 downto 0); clear: in std_logic; write_register : in std_logic; send_zeros_instead : in std_logic; clk : in std_logic; output_instruction : out std_logic_vector(31 downto 0) ); end IF_to_ID_registers; architecture Behavioral of IF_to_ID_registers is signal instruction_register : std_logic_vector(31 downto 0); begin process(clk) begin if clear = '1' then output_instruction <= (others => '0'); instruction_register <= (others => '0'); elsif rising_edge(clk) then if write_register = '1' then instruction_register <= fetched_instruction; end if; if send_zeros_instead = '1' then output_instruction <= (others => '0'); else output_instruction <= instruction_register; end if; end if; end process; end Behavioral;  

 

Thank you for your help 

 

EDIT: Also is there a way I can make the write level based, and the read edged based. I am getting some very nasty timing issues in modelsim.
(Virus scan in progress ...)
0 Kudos
Altera_Forum
Honored Contributor II
4,793 Views

You have asked for two register stages: 

 

fetched instruction => instruction_register then 

instruction register => output_instruction. 

 

If you just want one stage then remove instruction_register and assign input to output directly
0 Kudos
Altera_Forum
Honored Contributor II
4,742 Views

 

--- Quote Start ---  

You have asked for two register stages: 

 

fetched instruction => instruction_register then 

instruction register => output_instruction. 

 

If you just want one stage then remove instruction_register and assign input to output directly 

--- Quote End ---  

 

 

But by doing that, I can't use send zeros properly. I order for it to be right, the registers output has to be multiplexed with the send_zeros_instead as the selector. How would I get that done
0 Kudos
Reply