【问题标题】:How to generate delay in verilog for synthesis?如何在verilog中生成延迟以进行综合?
【发布时间】:2013-10-08 18:15:53
【问题描述】:

我想为接口 16*2 LCD 设计一个 Verilog 代码。就像在 LCD 中给出“命令”或“数据”一样,我们必须给 LCD 的启用引脚一个“高到低脉冲”脉冲,这意味着

**E=1;
Delay();//Must be 450ns wide delay
E=0;**

这是我混淆的地方,我的意思是在 Verilog 中进行综合 # 是不允许的,所以我怎么能在这里延迟,我在下面附上了我的代码。 必须注意,我尝试在我的代码中延迟,但我认为延迟不起作用,所以请帮助我摆脱这个延迟问题......

             ///////////////////////////////////////////////////////////////////////////////////
             ////////////////////LCD Interfacing with Xilinx FPGA///////////////////////////////
             ////////////////////Important code for 16*2/1 LCDs///////////////////////////////// 
             //////////////////Coder-Shrikant Vaishnav(M.Tech VLSI)/////////////////////////////
             ///////////////////////////////////////////////////////////////////////////////////

 module lcd_fpgashri(output reg [7:0]data,output reg enb,output reg rs,output reg rw ,input CLK);
        reg [15:0]hold;
        reg [13:0]count=0;
        //Code Starts from here like C's Main......
        always@(posedge CLK)
        begin
        count=count+1; //For Delay

       //For LCD Initialization   
        lcd_cmd(8'b00111000);
        lcd_cmd(8'b00000001);
        lcd_cmd(8'b00000110);
        lcd_cmd(8'b00001100);

       //This is a String "SHRI" that I want to display
        lcd_data(8'b01010011);//S
        lcd_data(8'b01001000);//H
        lcd_data(8'b01010010);//R
        lcd_data(8'b01001001);//I
        end


        //Task For Command

       task lcd_cmd(input reg [7:0]value); 
          begin
         data=value;
         rs=1'b0;
         rw=1'b0;
         enb=1'b1;        //sending high to low pulse
         hold=count[13]; //This is the place where I try to design delay
         enb=1'b0;
        end
        endtask


   //Task for Data      

    task lcd_data(input reg [7:0]value1);
        begin
         data=value1;
         rs=1'b1;
         rw=1'b0;
         enb=1'b1;        //sending high to low pulse  
         hold=count[13]; //This is the place where I try to design delay
         enb=1'b0;
        end 
        endtask


        endmodule

【问题讨论】:

标签: verilog


【解决方案1】:

您似乎陷入了基于您的代码的软件编程思维模式,如果您想真正用 HDL 描述控制器,您将不得不进行相当多的改变。

不幸的是,您无法像您在那里写的那样在“例程”中插入任意延迟。

当你写一个软件程序的时候,写一个像这样的程序是完全合理的

doA();
doB();
doC();

每行以顺序方式一次执行一个。 HDL 不能以这种方式工作。您无需考虑任务,而是开始考虑时钟和状态机。

请记住,当您有一个 always 块时,整个块在每个时钟周期并行执行。当你在 always 块中有这样的语句时:

    lcd_cmd(8'b00111000);
    lcd_cmd(8'b00000001);
    lcd_cmd(8'b00000110);
    lcd_cmd(8'b00001100);

这对你没有好处,因为所有这四个都在时钟的上升沿同时执行,而不是按顺序执行。您需要做的是创建一个状态机,以便它在一个时钟周期内前进并执行一个动作。

如果我尝试按顺序复制这四个 lcd_cmd,它可能看起来像这样。

always @(posedge clk)
    case(state_f)
       `RESET: begin
           state_f <= `INIT_STEP_1;
           data = 8'b00111000;
       end
       `INIT_STEP_1: begin
           state_f <= `INIT_STEP_2;
           data = 8'b00000001;
       end
       `INIT_STEP_2: begin
           state_f <= `INIT_STEP_3;
           data = 8'b00000110;
       end
       `INIT_STEP_3: begin
           state_f <= `INIT_STEP_4;
           data =8'b00111000;
       end
       `INIT_STEP_4: begin
           state_f <= ???; //go to some new state
           data = 8'b00000110;
       end
    endcase
end

现在使用此代码,您将在四个时钟周期内推进四个状态,因此您可以开始了解如何处理编写在每个时钟周期推进的事件序列。

这个答案并不能完全满足您的要求,因为在这些之间没有您想要的“延迟”。但是你可以想象有一个状态机,在设置数据后你进入延迟状态,你可以设置一个计数器,在进入下一个状态之前,你需要满足你的时序要求。

【讨论】:

  • +1 表示as there is no 'delay' in between these as you wanted。但是为什么要使用阻塞分配来分配数据呢?
  • 你说得对,应该是非阻塞的,我只是拼凑了一些伪代码,并没有充分校对。
  • 但是先生,我们在“顺序块”中写入的所有内容,即“开始-结束”都以顺序方式工作......所以我按顺序工作......如果我错了请告诉我.....
  • 块内的语句是按顺序评估的,但这些评估之间没有固有的延迟。在测试台中,您可以在这些语句中插入固定延迟,但它们是不可综合的。您必须开始考虑硬件,而不是软件。
  • 先生但我仍然不知道如何生成延迟根据数字设计中的蒂姆先生,延迟是通过使用“计数器”生成的,但我不知道如何为计数器制作代码......我的意思是我可以这样放置语句“N
【解决方案2】:

引入延迟的最佳方法是使用 Tim 提到的计数器。 找出您需要等待多少个时钟周期才能获得所需的延迟(此处为 450ns)w.r.t 您的时钟周期。

让我们计算计算的时钟周期数。在这种情况下,以下代码可以为您提供所需的延迟。但是,您可能需要根据自己的目的修改逻辑。

always @ (posedge clk) begin
  if (N == count) begin
    N <= 0;
    E = ~E;
  end else begin
    N <= N +1;    
  end 
end

确保将 N 和 E 初始化为零。

【讨论】:

  • 先生,我很困惑在您的代码中使用“计数器”生成“延迟”我知道计数器用于生成延迟但不知道如何根据要求使用它......我意思是为什么你像触发器一样使用 if 和 else 条件以及为什么你使用“E”......我的意思是为什么你不总是简单地使用并且在里面放置“N
  • 当您总是使用时,会涉及延迟,但是您如何将其纳入您的逻辑?这里“E”可以被视为您的逻辑的启用/时钟启用。因此,每次达到计数时,即获得所需的延迟,启用/clock_enable 切换。我使用了“E”,因为在您的要求中您也提到过它。见下文。 E=0 E=1
  • 先生,我可以这样使用吗....让我们考虑 1 个计数 = 1ns,然后对于 450ns,我需要 450 个计数,然后根据您的说法,这可以始终有效@(posedge clk)begin "mylogic" count
猜你喜欢
  • 1970-01-01
  • 2017-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多