如何在verilog中产生合成延迟?

Shr*_*nav 4 verilog

我想设计一个用于连接16*2 LCD的Verilog代码.如在LCD中给出"命令"或"数据",我们必须给LCD的Enable引脚一个"高到低脉冲"脉冲,这意味着

**E=1;
Delay();//Must be 450ns wide delay
E=0;**
Run Code Online (Sandbox Code Playgroud)

这个我混淆的地方我在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
Run Code Online (Sandbox Code Playgroud)

Tim*_*Tim 5

您似乎陷入了基于代码的软件编程思维模式中,如果您想在HDL中实际描述控制器,那么您将不得不改变一些事情.

不幸的是,你没有办法像你在那里写的那样,将一个任意延迟插入到"例行程序"中.

编写软件程序时,编写类似的程序是完全合理的

doA();
doB();
doC();
Run Code Online (Sandbox Code Playgroud)

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

请记住,当您有一个始终阻塞时,整个块在每个时钟周期并行执行.如果在always块中有这样的语句:

    lcd_cmd(8'b00111000);
    lcd_cmd(8'b00000001);
    lcd_cmd(8'b00000110);
    lcd_cmd(8'b00001100);
Run Code Online (Sandbox Code Playgroud)

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

如果我试图以顺序方式复制这四个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
Run Code Online (Sandbox Code Playgroud)

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

这个答案并没有让你一路走来,因为你想要的并没有"延迟".但你可以想象有一个状态机,在设置数据后你进入DELAY状态,在那里你可以设置一个计数器来计算足够的时钟周期,你需要在进入下一个状态之前满足你的时序要求.