如何等待始终阻止的边缘?

时间:2017-06-06 08:18:16

标签: verilog fpga quartus

我想写这样的东西:

always@(posedge bus_start)
begin
    @(posedge scl) buffer[7] = sda;
    @(posedge scl) buffer[6] = sda;
    @(posedge scl) buffer[5] = sda;
    @(posedge scl) buffer[4] = sda;
    @(posedge scl) buffer[3] = sda;
    @(posedge scl) buffer[2] = sda;
    @(posedge scl) buffer[1] = sda;
    @(posedge scl) buffer[0] = sda;
end

但根据我得到的错误,它无法合成。

我可能会使用FSM来解决这个问题,但这可能会让它变得复杂,有没有办法让它可以合成?

3 个答案:

答案 0 :(得分:1)

您没有提供足够的信息。

来自@ Krabby127的答案也不可合成。

我认为你还有很多工作要做。你应该首先了解Verilog和C之间的区别。 RTL代码用于描述FPGA中的硬件。因此,可合成的概念对您来说非常重要。

你必须处理I2C信号的去抖动。注意三态信号。 毕竟我建议你从opencores.org学习一些I2C项目。 原谅我可怜的英语。

答案 1 :(得分:0)

您似乎正在尝试从I2C接口捕获数据。 这是一个简单的解决方案,用于从sda捕获8位数据并将其存储到名为buffer的寄存器中。

// starts on rising edge of scl or bus_start
always@(posedge bus_start or posedge scl) 
begin
    buffer[0] <= sda; // loads sda into the lowest bit of buffer
    buffer[7:1] <= buffer[6:0]; // shifts the lower 6 bits one to
                                // the left, acting as a shift register
end

可以找到有关verilog中I2C的更多信息here 此外,可以找到基本的I2C从设备here(您必须注册并登录才能查看源代码)。

答案 2 :(得分:0)

I2C从设备主要使用SCL以外的采样时钟。我并不是说这是不可能的,但通常的做法是使用更快的时钟来采样SCL和SDA信号。

我绝对建议至少使用以下端口启动设计。由于SDA是一个三态信号,我也建议不要在这个阶段处理它。您可以假设它已从模块中完成,并可以继续使用单独的输入和输出端口。

input  clk;     // system clock
input  rst;     // system reset

input  scl;     // i2c clock
input  sda_in;  // i2c input data
output sda_out; // i2c output data

老实说,I2C不是学习HDL(Verilog / SV / VHDL)和数字设计的好选择。它会带来一些复杂的问题。