16-bit program counter register not producing correct outputs VHDL

I am trying to create a 16-bit program register using VHDL in Quartus II and I am having trouble getting the vwf to display the correct results based on my code. The counter takes in an input value, clock value, increment value, and reset value. All are active high and rising edge triggered.

Here is the code that I have:

--program counter register Khalid Abdallah
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity register_pc_AbdallahKhalid is
    port( din : in std_logic_vector(15 downto 0);
          clock, load, inc, reset : in std_logic;
          Q : inout std_logic_vector(15 downto 0));
end register_pc_AbdallahKhalid;

architecture behavior of register_pc_AbdallahKhalid is
begin
    process(clock)
    begin 
        if (rising_edge(clock)) then
            if reset <= '1' then
                Q <= "0000000000000000";
            elsif load <= '1' then
                Q <= din;
            elsif inc <= '1' then
                Q <= Q + 1;
            end if;
        end if;
    end process;
end behavior;

I need it to work using the following inputs for the vwf:

require inputs for the vwf

I am receiving no errors in the code and I have tried changing the type of Q to be out std_logic_vector but it did not producing anything.

  • Please edit your question and provide the test bench that produced the wave diagram. (Disclaimer: I did not down vote. It helps more if one provides helpful comments…)

    – 




  • Your comparisons are wrong, use = instead of <=.

    – 

Lets start from the beginning:

  • it is a better practice to use “NUMERIC_STD” library instead of “STD_LOGIC_ARITH” and you can find here more details about the raison. You can keep it but that is not recommended.
  • It is a better practice to write every entity port in a separate line.
  • You don’t need to define “Q” as “inout”(you are doing this because you get an error when you try to increment the value, you can not read an output port value) but instead you can use an intermediate signal and then assign it to output.
  • Use just “=”for comparison for input logic ports and not “<=”.
  • Use (others => ‘0’) to reset the initial value of the counter instead of the whole binary value(“0000000000000000”).

so given these “remarks” your code should be something like this:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity register_pc is
    port( din       : in std_logic_vector(15 downto 0);
          clock     : in std_logic;
          load      : in std_logic;
          inc       : in std_logic;
          reset     : in std_logic;
          Q         : out std_logic_vector(15 downto 0));
end entity register_pc;

architecture behavior of register_pc is

signal S_COUNT    : std_logic_vector(15 downto 0); -- count value

begin
    process(clock)
    begin 
        if (rising_edge(clock)) then
            if reset="1" then
                S_COUNT <= (others => '0'); -- better practice
            elsif load = '1' then
                S_COUNT <= din;
            elsif inc="1" then
                S_COUNT <= S_COUNT + 1;
            end if;
        end if;
    end process;
    
    Q   <= S_COUNT; -- assign counter value

end behavior;

You might think of making a separate testbench to test it.

Leave a Comment