如何在verilog中生成用于合成的延迟?

如何在verilog中生成用于合成的延迟?,verilog,Verilog,我想设计一个用于接口16*2 LCD的Verilog代码。在LCD中,为了发出“命令”或“数据”,我们必须给LCD的使能引脚一个“从高到低的脉冲”,这意味着 **E=1; Delay();//Must be 450ns wide delay E=0;** 这是我混淆的地方,我在Verilog for synthesis中的意思是不允许使用#,因此我如何在这里提供延迟,我在下面附上了我的代码必须注意的是,我尝试在代码中给出延迟,但我认为延迟不起作用,因此请帮助我解决此延迟问题……

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

**E=1;
Delay();//Must be 450ns wide delay
E=0;**
这是我混淆的地方,我在Verilog for synthesis中的意思是不允许使用#,因此我如何在这里提供延迟,我在下面附上了我的代码必须注意的是,我尝试在代码中给出延迟,但我认为延迟不起作用,因此请帮助我解决此延迟问题……

             ///////////////////////////////////////////////////////////////////////////////////
             ////////////////////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

你似乎陷入了一种基于代码的软件编程思维,如果你想用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
始终@(posedge clk)
案件(f州)
`重置:开始

state_f引入延迟的最佳方法是使用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
始终@(posedge clk)开始
如果(N==计数)开始

N+1表示
,因为它们之间没有您想要的“延迟”
。但是为什么数据分配使用阻塞分配呢?你是对的,它应该是非阻塞的,我只是拼凑了一些伪代码,没有充分校对。但是先生,我们在“顺序块”中写的所有东西都是“开始-结束”以顺序的方式工作…所以我认为它是按顺序工作的…如果我错了,请告诉我…块中的语句是按顺序计算的,但这些计算之间没有固有的延迟。在测试台中,您可以在这些语句中插入固定的延迟,但它们是不可合成的。你必须开始考虑硬件,而不是软件。先生,但我仍然不知道如何根据Tim Sir在数字设计中生成延迟。延迟是通过使用“计数器”生成的,但我不知道如何为计数器生成代码……我的意思是,我可以这样放置语句“在编写任何HDL之前查看此:先生,我不知道如何使用”“计数器”用于生成代码中的“延迟”,我知道计数器用于生成延迟,但不知道如何根据要求使用它……我的意思是,为什么要像触发器一样使用if和else条件,为什么要使用“E”……我的意思是,为什么不简单地始终在其中使用”当你使用它的时候,总是会有延迟,但是你如何把它纳入你的逻辑呢?这里“E”可以被视为逻辑的启用/时钟启用。因此,每次达到计数时,即达到所需延迟时,启用/时钟启用切换。我使用了“E”,因为在你的要求中,你也提到了它。见下文。E=0 E= 1SIR,我可以这样使用……让我们考虑1计数=1ns,然后为450ns,我需要450个计数,然后根据你可以这样做,总是@ @(PASEDGE CLK)开始“MyLogic”计数。