简体   繁体   中英

VHDL - Writing to FPGA Register

I have an FPGA with four push buttons - the two left most ones should cycle up and down the 16 registers, while the two right most ones should increment and decrement the value stored in this register. Here is my attempt at the code to do this:

entity raminfr is   --inferring the RAM here
    port (
        clk : in std_logic;
        we : in std_logic;
        a : in unsigned(3 downto 0);
        di : in unsigned(7 downto 0);
        do : out unsigned(7 downto 0)
    );
end raminfr;

architecture rtl of raminfr is

type ram_type is array (0 to 15) of unsigned(7 downto 0);
signal RAM : ram_type;
signal read_a : unsigned(3 downto 0);

begin
  U1: entity work.lab1 port map (  --ERROR ON THIS LINE
    register_counter => a,
    value_counter => di
  );
process (clk)
begin
    if rising_edge(clk) then
        if we = '1' then
            RAM(to_integer(a)) <= di;
        end if;
        read_a <= a;
    end if;
end process;
do <= RAM(to_integer(read_a));
end rtl;




--lab1 starts here
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity lab1 is 
    port(
        clock : in std_logic;
        key : in std_logic_vector(3 downto 0); 
        value_counter   : out unsigned(7 downto 0) ; --value to be written to register
        register_counter : out unsigned(3 downto 0) --register to write value to

        );
end lab1;

architecture up_and_down of lab1 is --actual button logic here
        begin
    process(clock)
        begin
            if rising_edge(clock) then
                if (key(3)='0' and key(2)='0' and key(1)='1' and key(0)='0') then
                    value_counter <= value_counter + "1";   
                elsif (key(3)='0' and key(2)='0' and key(1)='0' and key(0)='1') then  
                    value_counter <= value_counter - "1";
                elsif (key(3)='1' and key(2)='0' and key(1)='0' and key(0)='0') then
                    register_counter<= register_counter + "1";
                elsif (key(3)='0' and key(2)='1' and key(1)='0' and key(0)='0') then
                    register_counter<= register_counter - "1";
                end if;
            end if;
    end process;
end architecture up_and_down;

I get the error Error (10577): VHDL error at DE2_TOP.vhd(312): actual port "a" of mode "in" cannot be associated with formal port "register_counter" of mode "out" on the line indicated above. It is obvious this is not how I would go about doing what I want to do. Can someone shed some light on this?

Change your point of view: Put the RAM under the Pushbutton-FSM. Not vice versa.

This RAM description should be synthesiable. If not take a look in the Synthesis Guide of your tool vendor.

entity raminfr is   --inferring the RAM here
    port (
        clk : in  std_logic;
        we  : in  std_logic;
        a   : in  unsigned(3 downto 0);
        di  : in  unsigned(7 downto 0);
        do  : out unsigned(7 downto 0)
    );
end entity raminfr;

architecture rtl of raminfr is

type ram_type is array (0 to 15) of unsigned(7 downto 0);
signal RAM : ram_type;

begin
  process (clk)
  begin
    if rising_edge(clk) then
        if we = '1' then
            RAM(to_integer(a)) <= di;
        end if;
        do <= RAM(to_integer(a));
    end if;
  end process;
end architecture rtl;

You also forgot to activate the write enable for the RAM. Maybe you try this code (Always do a simulation first!):

--lab1 starts here
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity lab1 is 
  port(
    clock            : in std_logic;
    key              : in std_logic_vector(3 downto 0); 
    value_counter    : out unsigned(7 downto 0); --value to be written to register
    ram_data         : out unsigned(7 downto 0); --value from 'RAM-register'
    register_counter : out unsigned(3 downto 0) --register to write value to
  );
end lab1;

architecture up_and_down of lab1 is --actual button logic here
  signal value    : unsigned(7 downto 0) := (others => '0');
  signal ram_a    : unsigned(3 downto 0) := (others => '0');
  signal ram_we   : std_logic;

begin

  -- infer your RAM
  your_ram:  entity work.raminfr
    port map (
      clk => clock,   --: in  std_logic;
      we  => ram_we,  --: in  std_logic;
      a   => ram_a,   --: in  unsigned(3 downto 0);
      di  => value,   --: in  unsigned(7 downto 0);
      do  => ram_data --: out unsigned(7 downto 0)
    );

  process(clock)
  begin
    if rising_edge(clock) then
      -- default
      ram_we <= '0';

      -- change value
      if key(1) = '1' then
        value <= value + 1;
      end if;

      -- change value
      if key(0) = '1' then
        value <= value - 1;
      end if;

      -- change 'register'
      if key(3) = '1' then
        ram_a  <= ram_a + 1;
      end if;

      -- write value to register
      if key(2) = '1' then
        ram_we <= '1';
      end if;
    end if;
  end process;

  value_counter    <= value;
  register_counter <= ram_a;

end architecture up_and_down;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM