尝试在VHDL中创建内存总线时生成的闩锁

尝试在VHDL中创建内存总线时生成的闩锁,vhdl,Vhdl,我一直在尝试在FPGA中创建一个简单的内存,可以使用其他处理器写入。我知道我应该使用FPGA RAM,但有人告诉我,我可以使用下面的代码制作一个简单的寄存器: vcap_data_store : process(resetb,clk) begin if resetb = '0' then vcap_data_in11 <= "0000000000000000000000"; vcap_data_in12 <= "0000000000000000

我一直在尝试在FPGA中创建一个简单的内存,可以使用其他处理器写入。我知道我应该使用FPGA RAM,但有人告诉我,我可以使用下面的代码制作一个简单的寄存器:

vcap_data_store : process(resetb,clk)
begin
    if resetb = '0' then
        vcap_data_in11 <= "0000000000000000000000";
        vcap_data_in12 <= "0000000000000000000000";
        vcap_data_in13 <= "0000000000000000000000";
        vcap_data_in14 <= "0000000000000000000000";
    elsif (rising_edge(clk)) then
        vcap_data_in11 <= vcap_data_in_11;
        vcap_data_in12 <= vcap_data_in_12;
        vcap_data_in13 <= vcap_data_in_13;
        vcap_data_in14 <= vcap_data_in_14;
    end if;
end process;

vdi_input_gen : process(vdi_csb, vdi_wrb, vdi_indt)
begin

    if (vdi_csb = '0' and vdi_wrb = '0') then
        if vdi_addr = "00000" then
            vcap_data_in_11(15 downto 0) <= vdi_indt(15 downto 0);
        elsif vdi_addr = "00001" then
            vcap_data_in_11(21 downto 16) <= vdi_indt(5 downto 0);
        elsif vdi_addr = "00010" then
            vcap_data_in_12(15 downto 0) <= vdi_indt(15 downto 0);
        elsif vdi_addr = "00011" then
            vcap_data_in_12(21 downto 16) <= vdi_indt(5 downto 0);
        elsif vdi_addr = "00100" then
            vcap_data_in_13(15 downto 0) <= vdi_indt(15 downto 0);
        elsif vdi_addr = "00101" then
            vcap_data_in_13(21 downto 16) <= vdi_indt(5 downto 0);
        elsif vdi_addr = "00110" then
            vcap_data_in_14(15 downto 0) <= vdi_indt(15 downto 0);
        elsif vdi_addr = "00111" then
            vcap_data_in_14(21 downto 16) <= vdi_indt(5 downto 0);
                    end if;
    end if;

end process;
vcap_数据_存储:进程(重置B、clk)
开始
如果resetb='0',则

vcap_data_in11您描述的是异步逻辑。你少了一个钟。首先,一个好的开始是描述一个顺序过程,其中所有寄存器都被更新,以及一个异步部分,其中逻辑发生。看看 重要部分包括: --信号 信号Q,tempQ:

process (Clock, Reset)
begin
  if Reset = '0' then
    -- reset register, Q <= <init state>
  elsif rising_edge(Clock) then
    -- update Register, Q <= tempQ;
 end if;
end process;

process(sig1,sig2,...,sign)
  -- set tempQ <= func(input signals)
end process;
过程(时钟、复位)
开始
如果重置='0',则

--重置寄存器,Q我有两个单独的建议。第一个修复了代码的原样。第二个(推荐的)建议了一种更好的方法来为这个问题构建代码

首先,下面将修复您的代码,但这不是最佳答案。问题是因为第二个过程没有定义信号vcap_data_in_11中。。。未选择它们时获取。快速的答案是使用默认分配。注意,代码很难阅读,因为您选择的名称太相似

vdi_input_gen : process(vdi_csb, vdi_wrb, vdi_indt)
begin
   -- default assignments:
   vcap_data_in_11 <= vcap_data_in11 ;   -- tempQ <= Q;
   vcap_data_in_12 <= vcap_data_in12 ; 
   vcap_data_in_13 <= vcap_data_in13 ; 
   vcap_data_in_14 <= vcap_data_in14 ; 

   -- your other code goes here:
    if (vdi_csb = '0' and vdi_wrb = '0') then
        if vdi_addr = "00000" then
            vcap_data_in_11(15 downto 0) <= vdi_indt(15 downto 0);
        elsif vdi_addr = "00001" then
            vcap_data_in_11(21 downto 16) <= vdi_indt(5 downto 0);
        elsif vdi_addr = "00010" then
    . . . 

    end if;
end process;
vdi_输入生成:过程(vdi_csb、vdi_wrb、vdi_indt)
开始
--默认分配:

vcap_data_in_11首选
…elsif上升沿(时钟),然后…
但这是答案。是的。我会用同样的方法。刚刚从链接复制了示例:)。但是谢谢你的评论,我会很幸运地替换iTunes,我现在得到的是tempQ上的闩锁错误,我是不是遗漏了什么?我应该在灵敏度列表sig1 sig2中使用什么信号?输入信号?我使用了cs和wr信号。你所说的func(输入信号)是什么意思?我不能直接在那里打别针吗?我的意思是,我使用的vdi_indt是一个直接从输入引脚驱动的信号,如std_逻辑_向量。这是非法的吗?你能编辑你的问题并更新你的代码吗?在大多数情况下,锁存是由于进程敏感度列表中缺少信号或缺少默认值赋值造成的。@Fajar正如我所想的那样:并非每种情况下都会得到一个值。组合进程必须为每个可能的输入生成一个输出->这意味着在进程运行的任何情况下,都必须用新值填充\u xx信号中的vcap_data_。一个常见的解决方案是在流程开始时将“0”分配给他们。
vdi_input_gen : process(vdi_csb, vdi_wrb, vdi_indt)
begin
   -- default assignments:
   vcap_data_in_11 <= vcap_data_in11 ;   -- tempQ <= Q;
   vcap_data_in_12 <= vcap_data_in12 ; 
   vcap_data_in_13 <= vcap_data_in13 ; 
   vcap_data_in_14 <= vcap_data_in14 ; 

   -- your other code goes here:
    if (vdi_csb = '0' and vdi_wrb = '0') then
        if vdi_addr = "00000" then
            vcap_data_in_11(15 downto 0) <= vdi_indt(15 downto 0);
        elsif vdi_addr = "00001" then
            vcap_data_in_11(21 downto 16) <= vdi_indt(5 downto 0);
        elsif vdi_addr = "00010" then
    . . . 

    end if;
end process;
vcap_data_store : process(resetb,clk)
begin
    if resetb = '0' then
        vcap_data_in11 <= "0000000000000000000000";
        vcap_data_in12 <= "0000000000000000000000";
        vcap_data_in13 <= "0000000000000000000000";
        vcap_data_in14 <= "0000000000000000000000";
    elsif (rising_edge(clk)) then
      if (vdi_csb = '0' and vdi_wrb = '0') then
        case vdi_addr is
          when "00000" =>   vcap_data_in11(15 downto 0)  <= vdi_indt(15 downto 0);
          when "00001" =>   vcap_data_in11(21 downto 16) <= vdi_indt( 5 downto 0);
          when "00010" =>   vcap_data_in12(15 downto 0)  <= vdi_indt(15 downto 0);
          when "00011" =>   vcap_data_in12(21 downto 16) <= vdi_indt( 5 downto 0);
          when "00100" =>   vcap_data_in13(15 downto 0)  <= vdi_indt(15 downto 0);
          when "00101" =>   vcap_data_in13(21 downto 16) <= vdi_indt( 5 downto 0);
          when "00110" =>   vcap_data_in14(15 downto 0)  <= vdi_indt(15 downto 0);
          when "00111" =>   vcap_data_in14(21 downto 16) <= vdi_indt( 5 downto 0);
          when others  =>   null ; -- do nothing !
        end case;
      end if;
    end if;
end process;