gpt4 book ai didi

verilog - 如何在verilog中生成延迟以进行合成?

转载 作者:行者123 更新时间:2023-12-03 20:37:25 47 4
gpt4 key购买 nike

我想设计一个用于连接 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

最佳答案

您似乎陷入了基于代码的软件编程思维模式,如果您想用 HDL 实际描述 Controller ,您将不得不进行相当多的更改。

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

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

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

每行以顺序方式一次执行一个。 HDL 不以这种方式工作。你不需要从任务的角度思考,而是从时钟和状态机的角度开始思考。

请记住,当您有一个 always 块时,整个块在每个时钟周期并行执行。当您在 always 块中有这样的语句时:
    lcd_cmd(8'b00111000);
lcd_cmd(8'b00000001);
lcd_cmd(8'b00000110);
lcd_cmd(8'b00001100);

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

如果我尝试以顺序方式复制这四个 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

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

这个答案并没有让你一路走好,因为在这些之间没有你想要的“延迟”。但是您可以想象有一个状态机,在设置数据后您将进入 DELAY 状态,您可以在其中设置一个计数器,该计数器可以倒计时足够的时钟周期,以满足您在进入下一个状态之前的时序要求。

关于verilog - 如何在verilog中生成延迟以进行合成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19232611/

47 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com