VHDL - FSM 未启动(仅在时序仿真中)

2024-03-22

我正在写我的硕士论文,而且我对 VHDL 还很陌生,但我仍然必须实现一些复杂的东西。这是我必须编写的最简单的结构之一,但我仍然遇到了一些问题。

它是一个 FSM,采用低电平有效同步信号(用于对 DAC 进行编程)实现 24 位移位寄存器。这只是我为项目创建的复杂细化链的末端。我尽可能地遵循 FSM 的示例模型。

行为模拟工作得很好,实际上,就行为模拟而言,我创建的整个细化链工作得非常好。然而,一旦我尝试翻译后模拟,事情就开始出错:大量“X”输出信号。

使用这个简单的移位寄存器,我没有得到任何“X”,但是我无法进入 load_and_prepare_data 阶段。似乎 current_state 发生了变化(通过检查一些信号),但详细说明没有继续。

请记住,由于我是这门语言的新手,所以我不知道应该在此 FSM 上设置什么时序约束(而且我也不知道如何将它们写在 top.ucf 上)

你能看出出了什么问题吗? 提前致谢

EDIT

我听从了您的建议,并使用单一状态进程清理了 FSM。我仍然对“在哪里放置什么”有些疑问,但我真的很喜欢新的实现。不管怎样,我现在得到了一个干净的行为模拟,但在翻译后模拟的所有输出上都是“X”。 是什么原因造成的? 我将发布新代码和测试平台:

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:44:03 11/28/2014 
-- Design Name: 
-- Module Name:    dac_ad5764r_24bit_sr_programmer_v2 - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: This is a PISO shift register that gets a 24bit parallel input word.
--              It outputs the 24bit input word starting from the MSB and enables
--              an active low ChipSelect line for 24 clock periods.
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity dac_ad5764r_24bit_sr_programmer_v2 is
    Port ( clk : in  STD_LOGIC;
           start : in  STD_LOGIC;
           reset : in  STD_LOGIC; -- Note that this reset is for the FSM not for the DAC
           reset_all_dac : in STD_LOGIC;
           data_in : in  STD_LOGIC_VECTOR (23 downto 0);
           serial_data_out : out  STD_LOGIC;
           sync_out : out  STD_LOGIC; -- This is a chip select
           reset_out : out STD_LOGIC;
           busy : out STD_LOGIC
         );
end dac_ad5764r_24bit_sr_programmer_v2;

architecture Behavioral of dac_ad5764r_24bit_sr_programmer_v2 is

-- Stati
type state_type is (idle, load_and_prepare_data, transmission);
--ATTRIBUTE ENUM_ENCODING : STRING; 
--ATTRIBUTE ENUM_ENCODING OF state_type: TYPE IS "001 010 100";
signal state: state_type := idle;
--signal next_state: state_type := idle;

-- Clock counter
--signal clk_counter_enable : STD_LOGIC := '0';
signal clk_counter : unsigned(4 downto 0) := (others => '0');

-- Shift register
signal stored_data: STD_LOGIC_VECTOR (23 downto 0) := (others => '0');

begin

FSM_single_process: process(clk)
begin
    if rising_edge(clk) then
        if reset = '1' then
            serial_data_out <= '0';
            sync_out <= '1';
            reset_out <= '1';
            busy <= '0';
            state <= idle;
        else
            -- Default
            serial_data_out <= '0';
            sync_out <= '1';
            reset_out <= '1';
            busy <= '0';

            case (state) is
                when transmission =>
                    serial_data_out <= stored_data(23);
                    sync_out <= '0';
                    busy <= '1';
                    clk_counter <= clk_counter + 1;
                    stored_data <= stored_data(22 downto 0) & "0";
                    state <= transmission;
                    if (clk_counter = 23) then
                        state <= idle;
                    end if;
                when others => -- Idle
                    if start = '1' then
                        serial_data_out <= data_in(23);
                        sync_out <= '0';
                        reset_out <= '1';
                        busy <= '1';
                        stored_data <= data_in;
                        clk_counter <= "00001";
                        state <= transmission;
                    end if;
            end case;

--            if (reset_all_dac = '1') then
--              reset_out <= '0';
--          end if;
        end if;
    end if;
end process;


end;

和测试台:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--USE ieee.numeric_std.ALL;

ENTITY dac_ad5764r_24bit_sr_programmer_tb IS
END dac_ad5764r_24bit_sr_programmer_tb;

ARCHITECTURE behavior OF dac_ad5764r_24bit_sr_programmer_tb IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT dac_ad5764r_24bit_sr_programmer_v2
    PORT(
         clk : IN  std_logic;
         start : IN  std_logic;
         reset : IN  std_logic;
         data_in : IN  std_logic_vector(23 downto 0);
         serial_data_out : OUT  std_logic;
         reset_all_dac : IN std_logic;
         sync_out : OUT  std_logic;
         reset_out : OUT  std_logic;
         --finish : OUT  std_logic;
         busy : OUT  std_logic
        );
    END COMPONENT;


   --Inputs
   signal clk : std_logic := '0';
   signal start : std_logic := '0';
   signal reset : std_logic := '0';
   signal data_in : std_logic_vector(23 downto 0) := (others => '0');
   signal reset_all_dac : std_logic := '0';

    --Outputs
   signal serial_data_out : std_logic;
   signal sync_out : std_logic;
   signal reset_out : std_logic;
   --signal finish : std_logic;
   signal busy : std_logic;

   -- Clock period definitions
   constant clk_period : time := 100 ns;

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: dac_ad5764r_24bit_sr_programmer_v2 PORT MAP (
          clk => clk,
          start => start,
          reset => reset,
          data_in => data_in,
          reset_all_dac => reset_all_dac,
          serial_data_out => serial_data_out,
          sync_out => sync_out,
          reset_out => reset_out,
          --finish => finish,
          busy => busy
        );

   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;


   -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
      wait for clk_period*10;
      reset <= '1' after 25 ns;
      wait for clk_period*1;
      reset <= '0' after 25 ns;
      wait for clk_period*3; 
      reset_all_dac <= '1' after 25 ns;
      wait for clk_period*1;
      reset_all_dac <= '0' after 25 ns;
      wait for clk_period*5; 
      data_in <= "111111111111111111111111" after 25 ns;
      wait for clk_period*3;
        start <= '1' after 25 ns;
      wait for clk_period*1;
        start <= '0' after 25 ns;


      wait;
   end process;

END;

UPDATE 1

使用最后的设计进行更新:此代码不会导致任何“X”(无法弄清楚为什么,这不会,但上一个会导致)。然而,它并没有像前 3 个进程机器一样启动(在 POST-TRANSLATE 模拟中),并且信号sync_out 停留在 0,而默认情况下它应该为“1”。

UPDATE 2

我一直在研究技术原理图,从sync_out = 0的问题开始:它是用FDS实现的,S是FSM重置信号,D来自LUT3,其中I =状态&重置&开始并且INIT = 45 =“00101101 ”。我在模拟中寻找了这个 LUT3,我注意到它有初始化=“00000000”!

关于如何运行此模拟,我是否缺少某些内容?看来设计中的每一个LUT都没有设置好!

UPDATE 3 It seems that the Post-Translate simulation is buggy in some way, or I'm not configuring it correctly for some reason: the Post-Map and the Post-PAR simulations work and display some outputs. However there is an odd bug: the stored_data register is not updated with the complete data_in vector, after that, the FSM operates correctly and outputs the data stored. I've looked in the tecnology schematic just after synthesis and for some reason the bits 23,22,21,19,18 are not connected to the corresponding data_in bit. You can see the effect in this screenshot from Post-Map simulation. Same happens in Post-PAR, but it seems that this problems comes directly from the synthesis! Stored_Data =/= Data_in

Solved:奇怪的输出来自综合优化。该工具意识到,对于这些特定位,精化链中的前一个块永远不会输出与 0 不同的位。我的错误在于假设我可以单独测试单个模块:我真正测试的是为 FPGA 综合的模块,同时考虑了设计中的其他所有内容!

感谢大家对我的帮助,我会听从你们的建议!


我更喜欢状态机的单进程形式,它更干净、更简单,并且更不容易出现敏感度列表错误等错误。我也赞同佩贝尔斯出色回答中的观点。但我认为这些都不是这里的问题。

在合成后和 PAR 后模拟中需要注意的一件事是,它们的时间模型与行为模型不同。行为模型遵循我在中描述的简单规则这个答案 https://stackoverflow.com/questions/13954193/is-process-in-vhdl-reentrant/13956532#13956532并确保在典型的设计流程中,您可以直接进入硬件 - 无需合成后仿真,无需担心。

事实上,如果我正在追踪可疑的工具错误,我只会使用合成后或 PAR 后模拟。 (对于 FPGA 设计,而不是 ASIC!)

然而,这种简单的时序模型有其局限性。您可能熟悉诸如通过信号分配分配的时钟信号(通常隐藏在您不希望的第三方模型中)之类的问题,它会消耗增量周期,并确保您的时钟数据到达before你的时钟而不是after,随后一切都会比预期早一个周期发生......

在行为建模中,一点点纪律就可以避免这些麻烦。但 PAR 后建模却并非如此。

您的测试平台的设置方式可能与行为模型相同。如果是这样,那很可能就是问题所在。

这就是我在这种情况下所做的:我没有正式的权威,只是经验。当将 FPGA 连接到具有实际时序的外部存储器模型时,它也能很好地工作。

1)我假设简单(行为)时序模型对于设计内部的所有信号都能正确工作。

2)我对设计的输入和输出没有任何假设。

3) 我记下输入上的估计建立和保持时序,(a) 来自 FPGA 数据表或更好的数据表,(b) 来自合成后或 PAR 报告中显示的最坏情况值,并构建试验台在他们旁边。 工作示例:建立时间 1 ns,保持时间 2 ns,时钟周期 10 ns。这意味着时钟沿后 2 ns 到 9 ns 之间的任何输入都保证能被正确读取。我(任意)选择 5 ns。

signal_to_fpga <= driving_value after 5 ns;

(请注意,Xilinx 通过将它们表示为“之前/之后的偏移输入/输出”来使这一点荒谬地违反直觉,这将时序指的是前一个或未来的时钟边沿,而不是您正在查看的时钟边沿)

或者,如果输入来自现实世界中的 CPU 或内存,我会使用该设备的数据表时序规范。

4) 我记下数据表或报告中报告的最坏情况 clk-out 时序,并构建design在他们旁边。 (比如说,7 纳秒)

fpga_output_pin <= driving_value after 7 ns;

请注意,这个“after”子句显然被综合忽略了;然而,后合成器反注释将引入非常类似的东西。
5)如果结果证明这还不够好,那么(可能在包装器组件中以避免污染可综合代码)提高准确性,例如

fpga_output_pin <= 'X' after 1 ps, driving_value after 7 ns;

6)我重新运行行为模拟。通常,它现在会失败,因为它是在没有考虑实际时间的情况下编写的。

7)我修复这些故障。这可能包括在测试设计输出值之前添加实际延迟。它可以是一个迭代过程。

现在,我有一个合理的期望,即 PAR 后仿真模型将直接进入测试平台并工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VHDL - FSM 未启动(仅在时序仿真中) 的相关文章

  • VHDL - PhysDesignRules:367

    当我尝试从 VHDL 代码合成 实现和生成程序文件时 我收到警告 当我尝试合成时出现此错误 WARNING Xst 647 Input
  • 将整数转换为 std_logic

    假设你有一个循环 for i in 1 downto 0 loop for j in 1 downto 0 loop tS0 lt i 但我需要将整数 这是自然的 转换为 std logic tS0被声明为 std logic 我只做了一位
  • Quartus初始化RAM

    我制作了一个实体 其中 quartus 成功识别 RAM 并为其实例化 RAM 宏功能 如果我可以从文件初始化 RAM 那就太好了 我找到了制作此类文件 mif 文件 的教程 现在我已经创建了该文件 我不知道如何让 quartus 初始化该
  • 有限状态机和 FSM 间信令

    对具有本机 因此没有 FSM 生成工具 支持状态机开发的语言的建议执行以及消息 信号的传递 这适用于电信 例如实现这种复杂程度的 FSM 我考虑过 Erlang 但希望得到一些反馈 建议 教程指针 替代方案 特别是基于 Java 的框架 也
  • 敏感列表中的哪个信号触发该过程

    在VHDL中 当模拟测试平台时 我有一个过程和一个敏感度列表 是否可以查看敏感列表中的哪个信号触发了该过程 我知道这可能取决于工具 我正在使用 Xilinx ISE 模拟器是否提供此信息 您可以使用 transaction属性结合 even
  • TouchsMoved 以不规则的间隔调用

    我正在为 iOS 制作一款游戏 您主要在屏幕上拖动大对象 当我在实际的 iPad iPhone 上运行游戏一段时间 连续在屏幕上画圈拖动对象 时 每隔 5 分钟左右拖动的对象会卡顿约 10 30 秒 然后 它又恢复如丝般光滑的移动状态 从视
  • 赋值语句中的“others=>'0'”是什么意思?

    cmd register process rst n clk begin if rst n 0 then cmd r lt others gt 0 elsif clk event and clk 1 then cmd r lt end if
  • 在VHDL中将8位二进制数转换为BCD

    该算法众所周知 您进行 8 次左移 并在每次移位后检查个位 数十位或数百位 每个 4 位 如果它们超过 4 个 则将 3 个添加到该组中 依此类推 这是一个基于流程的解决方案 但不起作用 它会编译 但输出不是我想要的 有什么想法可能是什么问
  • VHDL 中数组的硬件表示

    使用 VHDL 我想要一些寄存器 每个寄存器存储 16 位 所以我发现VHDL有一个内置数组 我想用它来存储iy中每个元素的16位 所以我想知道VHDL是否将此数组映射到实际寄存器 简短的回答是否定的 数组类型不映射到寄存器 长答案 VHD
  • 对 Python 正在处理其输出的外部程序进行计时

    我想测量我的 Python 脚本使用其输出的外部程序的执行时间 Calling extprogram产生输出的程序 目前我做了类似的事情 import time import subprocess def process output li
  • vhdl中process语句的顺序执行

    对于vhdl中的process语句 据说process语句内部的执行顺序是连续的 我的问题是 请先看下面的代码 a b和c信号在进程语句中的if语句中是同时还是顺序分配给它们的新值 process clk is begin if risin
  • 在 VHDL 中使用 SB_RGBA_DRV 原语

    我在使用为 Lattice ICE40UP fpga 提供的 SB RGBA DRV 原语时遇到问题 技术库提供了一个 verilog 示例 我可以使用它 但是当我尝试在 VHDL 中使用它时 P R 失败 输出以下消息 错误 非法连接 S
  • vhdl代码(for循环)

    描述 我想编写 vhdl 代码来查找数组 A 中的最大整数 该数组是一个由 20 个整数组成的数组 问题 我的算法应该是什么样子 以输入顺序语句的位置 我的VHDL代码 highnum for i in 0 to 19 loop i 0 i
  • 在单周期数据路径中加载半字和加载字节

    有人询问如何在单周期数据路径中实现加载字节而无需更改数据存储器 解决方案如下 替代文本 http img214 imageshack us img214 7107 99897101 jpg http img214 imageshack us
  • Sql触发器是同步的还是异步的?

    我有一个表 上面有一个插入触发器 如果我通过存储过程的一个插入语句将 6000 条记录插入到该表中 存储过程会在插入触发器完成之前返回吗 只是为了确保我的想法正确 触发器应该只被调用一次 我知道 被调用 不是正确的词 一次 因为只有 1 个
  • 用几个 1 位 ALU 制作一个 4 位 ALU

    我正在尝试将几个 1 位 ALU 组合成一个 4 位 ALU 我对如何在 VHDL 中实际执行此操作感到困惑 这是我正在使用的 1 位 ALU 的代码 component alu1 define the 1 bit alu componen
  • 在上下文中模拟计时,以使用 auto_now_add=True 的字段 DateTimeField 创建模型

    我想模拟时间以便能够set特定时间到某个类型的字段DateTimeField with auto now add True在我的测试期间 例如 class MyModel created at models DateTimeField au
  • VHDL 中的 if 语句

    我有一个关于 VHDL 中 if 语句的问题 请参见下面的示例 signal SEQ bit vector 5 downto 0 signal output bit if SEQ 000001 and CNT RESULT 111111 t
  • 如何在不同的班级中启动和停止计时器?

    我想测量从传入 HTTP 请求开始到应用程序到达某个点的时间 这两个时间点都位于不同的类中 我将如何启动和停止这些不同类别的计时器 我没有看到使用 MeterRegistry 中的 命名 计时器的方法 我该怎么办呢 您可以使用 AOP 如下
  • 使用 if 语句更改进程内的信号 - VHDL

    我有这个 VHDL 代码 我想要的是在 sw event 时首先上升 然后 首先自行下降 但当我模拟这个时 首先永远不会跌倒 process rst clk sw begin if clk EVENT and clk 1 then if r

随机推荐