如何使用合成计数器并在Always块内调用在Verilog中生成延迟? [英] How to generate delay in verilog using Counter for Synthesis and call inside Always block?
问题描述
我想使用计数器生成延迟,实际上,在这里我使用计数器在每传输1位数据后生成延迟,以便更好地从外部了解SPI(串行)LCD与之连接的fpga引脚.因此,我创建了一个移位寄存器,先移位1位,然后再延迟下一位(Bit-Delay-bit-delay ..).
I want to generate delay using counter, actually here I use counter to generate delay after each 1 Bit transfer, so that its better understand externally on fpga pin from which by SPI(serial) LCD is connected with it. Therefore I had created a shift register which shift 1 bit then gives delay then next bit(Bit-Delay-bit-delay..).
这是我的柜台代码:
module spidelay(
input wire clk,
input wire enb,
output reg sclkout
);
reg [23:0] stmp;
always @(posedge clk) begin
if ( enb == 1 ) begin
stmp = stmp+1;
if( stmp[23] == 1 ) begin
sclkout = 1'b1;
stmp = 24'b0;
end
end
else begin
stmp = 24'b0;
sclkout = 1'b0;
end
end
endmodule
朋友,但问题在于我不知道如何在always block
内部启用/启动计数器.我的意思是我不知道我们如何在要始终产生延迟的行上启动/启用计数器.
Friends but problem with it is I don't know how to enable/start counter inside always block
I mean I don't know how can we start /enable counter at line which we want to generate delay inside always.
现在这是我的Top模块的代码,我想从该模块中生成特定行的延迟--- >>
Now this is the code of my Top module from which I want to generate delay in particular line--->>
module Nokia_LCD(input clk,input switch,output OUT,output reset,inout sck,output cs);
wire clk;//On Board Clock
wire switch;//Switch For RESET
integer i;
integer z;//Used for, for loop for generating delay
reg signed OUT;//OUT for sending Data serially to LCD
reg reset=1'b1;//To Reset LCD
wire sck; //We select sck as inout because it taking input from counter Instance and then gives output to LCD..
reg cs; //Chip select pin of lcd always set to zero
reg signed[8:0]out;//Register for Storing value of OUT
reg [5:0]state =6'b000000; //Initialize states to Zero
reg [7:0]finder; //Finder finds the state that was last present in it so that by this we again go to that state sequentially
reg [7:0]font[1:0][5:0];//2-D Array of 8 Bit For Font
reg [23:0]stmp=24'b00000_00000_00000_00000_0000;
reg enb;
wire sclkout;
counter count1(clk,sck);//Instance of Counter1 for SCK Clock
spidelay count2(clk,enb,sclkout);
always@(posedge clk)
begin
case (state)
/* Lcd Initialization starts from here*/
6'b000000 : begin
finder=8'b00000000;
cs=1'b0;
out=9'b0_00010001; //Using Command SLEEPOUT (Hex 0x11) - Exits LCD sleep mode
state=6'b010001;
end
6'b000001: begin
finder=8'b00000001;
cs=1'b0;
out=9'b0_00000011; //Using Command BSTRON (Hex 0x03) - Turns on booster voltage
state =6'b010001;
end
/******************************************************************************************************************/
/************************************ State for SPI Data Transfer & Delay *****************************************/
/******************************************************************************************************************/
6'b010001:begin
//We Use finder to find the state from which it Comes...
if(finder==8'b00000000) //for 0
begin:close1
cs=1'b0;
for(i=0;i<=8;i=i+1)
begin
out=out<<<1;
OUT=out[8];
enb=1'b1; <<<<<<<-----|This is the place where I want it to enable counter and it must stop here for counting and during this time it not move for othe count of for loop......
if(stmp[23]==1'b1)
begin
disable close1;
end
end
state=6'b000001;//Go to State 000001(BSTRON)
end
endcase
end //Always end
endmodule
必须注意,我对Friends进行了编辑,以便专注于错误点....因此,如果在某个地方发现语法错误,则可以忽略它,但是请帮助我并提出一些建议,以免延迟Toppest模块始终通过提供enb = 1'b1 .......
It must be noted that Friends I am edited it so that to concentrate on the point of of error....so if somewhere you find error in syntax then ignore it but please help me and give some suggestion to generate delay on Toppest Module's always block by giving enb=1'b1 .......
推荐答案
建议在边缘触发块always @( posedge ...
您提到延迟,我认为您是指延迟固定数量的时钟周期.在这种情况下,您就是这样做的,只是在不满足计数器要求时才重置sclkout.
You mention delays I assume you are referring to delaying by a fixed number of clock cycles. In which case this is what you have done, you just have not reset the sclkout when not meeting the counter requirements.
if ( enb == 1 ) begin
sclkout <= 1'b0; //Reset by default
stmp <= stmp+1;
if( stmp[23] == 1 ) begin //Counter target
sclkout <= 1'b1;
stmp <= 24'b0;
end
end
else begin
//...
或添加else
if ( enb == 1 ) begin
if( stmp[23] == 1 ) begin //Counter target
sclkout <= 1'b1;
stmp <= 24'b0;
end
else begin
sclkout <= 1'b0; //Reset by default
stmp <= stmp+1;
end
end
else begin
//...
注意:输入是隐式接线,如果您不想这样做,则不必编写. input wire clk
与input clk
相同.
NB: inputs are implicitly wires you do not have to write it if you do not want to. input wire clk
is the same as input clk
.
我还将为您的比较添加一个宽度,即== 1'b0
而不是== 0
,否则稍后在设计流程中,您将收到宽度不匹配警告.
I would also add a width to your comparisons, ie == 1'b0
instead of == 0
, otherwise later on in you design flow you will get width mismatch warnings.
更新
根据注释中添加的信息,要求计数器在enb==1'b1
时停止,我假设代表"enable bar"
Update
Based on information add in the comment, the requirment is for the counter to stop when enb==1'b1
, I am assuming that stands for 'enable bar'
always @ (posedge clk) begin
if ( enb == 1'b0 ) begin
// When enable bar is low this is Active
stmp <= stmp + 1'b1;
// etc ...
end
//else begin
// Do Nothing (hold state)
//end
end
这篇关于如何使用合成计数器并在Always块内调用在Verilog中生成延迟?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!