发送串行字节的简单VHDL测试台程序?

发送串行字节的简单VHDL测试台程序?,vhdl,fpga,hdl,Vhdl,Fpga,Hdl,我试图在我的设计中消除比特攻击,并使用一个过程从DUT外部发送测试信号。序列化消息的格式为起始位“0”、以MSB开头的字节和停止位“1”。该线在“1”处空转。我想我在使用过程和主进程之间传递的数据类型时遇到了问题 以下是我的程序(波特率是串行时钟周期的时间常数): 过程发送midi字节( 信号字节_in:标准逻辑_向量中; 信号midi_输出:输出标准逻辑)为 开始 midi输出问题 你有两个错误。第一,布莱恩指出,你的射程是错误的。表示范围的一种简单方法是使用“范围”。这在下面的代码中显示 此

我试图在我的设计中消除比特攻击,并使用一个过程从DUT外部发送测试信号。序列化消息的格式为起始位“0”、以MSB开头的字节和停止位“1”。该线在“1”处空转。我想我在使用过程和主进程之间传递的数据类型时遇到了问题

以下是我的程序(波特率是串行时钟周期的时间常数):

过程发送midi字节(
信号字节_in:标准逻辑_向量中;
信号midi_输出:输出标准逻辑)为
开始
midi输出问题
你有两个错误。第一,布莱恩指出,你的射程是错误的。表示范围的一种简单方法是使用“范围”。这在下面的代码中显示

此外,您希望将参数中字节_的类更改为常量,如下代码所示

解决方案

  procedure send_midi_byte (
    constant byte_in  : in  std_logic_vector;
    signal   midi_out : out std_logic
  ) is
  begin
    midi_out <= '0';
    wait for baudrate;
    for i in byte_in'range loop
      midi_out <= byte_in(i);
      wait for baudrate;
    end loop;
    midi_out <= '1';
    wait for baudrate;
  end send_midi_byte;
您已经熟悉了这一点,因为所有的语言操作符(实现为函数)都有常量类参数(这是默认值,在标准包中通常不使用)

参数指南
对于输入:
当需要对对象进行更新时,使用信号,例如使用“事件”,或在等待语句中使用对象。通常这意味着对象来自体系结构(如DUT)。
需要传递文本值时,请使用常量

对于输出:
将值传递给架构(如DUT)时使用信号。
将值传递回本地进程时使用变量

为什么参数应该是常量
在您的示例中,它将与信号一起工作,但是,使用模型将始终是:1)分配给信号,然后2)调用子程序:

byte_slv <= x"90";
send_midi_byte(byte_slv, midi_in_int);

byte_slv以及Jim的建议,修复循环范围并重试,然后再尝试其他操作<代码>7到0是一个空范围;
0到7
7到0
都不是

非阻塞(关于赋值)在VHDL中是一个毫无意义的术语,但在过程中的循环中进行信号赋值是绝对正确的。这是一个延迟的任务,计划在
等待波特率开始时执行。当然,它会等待指定的时间,下一个循环迭代在完成后开始

我已经尝试了几种不同的方法,这是唯一一种没有给出错误的方法,但它当然不会起作用,因为过程中的非阻塞分配意味着我的串行信号在波特率指定的时间长度内仅为“1”

你在这里断言的前提是不正确的。过程调用失败的原因是循环参数规范提供了空范围(首先计算循环参数,循环语句执行0次或更多次)

如何正确编写此过程

一个最小的、完整的、可验证的示例,其修复程序包含在过程
send_midi_byte
中:

ieee库;
使用ieee.std_logic_1164.all;
实体cmoc_cmoc为
终端实体;
cmoc的体系结构mcve\u cmoc是
恒定波特率:时间:=26.925 us;——38.400波特
程序发送midi字节(
信号字节_in:标准逻辑_向量中;
信号midi_输出:输出标准逻辑
)是
字节中的别名:标准逻辑向量(7到0)是字节补充
开始

midi_感谢您提供了有关传递参数的信息,但现在我相信我又回到了并发语句的问题上,至少对于我的for循环来说是这样。模拟现在将midi_in_int设置为0表示波特率时间,将midi_in_int设置为1表示波特率时间,然后重置。好像for循环不在那里。与该结构有关吗?请注意,OP循环参数规范的方向提供了一个空范围。常量表示该参数在子程序的生命周期内是静态的。在子程序调用的生存期内。参数值是动态细化的。另请注意
中模式
参数的默认类为常量。你的回答错了,原来的帖子没有提供答案。注意,在循环退出之前,顺序进程调用不会完成。@user1155120感谢您的更正。应该注意的是,子程序只有在被调用时才会被详细说明,因此对于VHDL人员来说,生命周期只能指子程序调用,然而,鉴于Verilog/Systevilog,我按照您的建议将子程序的生命周期更改为子程序调用。还应该注意的是,具有空范围的循环不是错误-它只是不进行迭代,因此循环将立即退出或可能永远不会进入。请修复循环范围,然后在尝试其他任何操作之前重试。虽然问题中的用法不正确,但我不认为在VHDL中非阻塞是一个毫无意义的术语。您当然可以使用VHDL来实现一些重要的东西。例如,必须非常清楚地记录哪些函数是阻塞的,哪些是非阻塞的。@Harry编辑以澄清。但函数肯定不能被阻塞吗?(虽然程序当然可以)。这很好,解决了问题。很高兴知道“X到Y”给出了一个空范围。X到Y只有在X较大时才给出空范围。解决方案有问题,因为它总是需要两个步骤。步骤1:分配给信号。第二步:打电话subprogram@JimLewis-你是在谴责(这里)缺乏答案,并且本可以要求(问题作者)提供更多信息,而不是从整体上制造一个困境。这里对多字节消息的唯一要求是,调用过程时,对信号字节的赋值有效。这里是停止位(最后的
等待波特率;  procedure send_midi_byte (
    constant byte_in  : in  std_logic_vector;
    signal   midi_out : out std_logic
  ) is
  begin
    midi_out <= '0';
    wait for baudrate;
    for i in byte_in'range loop
      midi_out <= byte_in(i);
      wait for baudrate;
    end loop;
    midi_out <= '1';
    wait for baudrate;
  end send_midi_byte;
send_midi_byte(x"90", midi_in_int);
for i in 0 to 10 loop
  send_midi_byte(x"90" + i, midi_in_int);
end loop;
byte_slv <= x"90";
send_midi_byte(byte_slv, midi_in_int);
procedure send_inc_midi_bytes (
  constant first_byte_in : in std_logic_vector;
  constant number_bytes  : in integer ;
  signal midi_out  : std_logic
) is 
   -- signal byte_in : std_logic_vector(7 downto 0); -- want to do this
begin
  for i in 0 to number_bytes - 1 loop
    byte_in <= byte_in + i ; 
    send_midi_byte(byte_in, midi_out);
  end loop ;
end procedure send_inc_midi_bytes ;