是调用子程序。例子:clk(clk1ms_tick),这里面的小数点是固定的调用端口格式,clk是子模块的输出端口,括号里面的clk1ms_tick是映射到主程序使用的端口。就是说在主程序里面clk1ms_tick相当于子模块的clk。调用子模块端口前面必须加小数点。
module HDLC(RXD,RXCLK,RXSET,TXCLK,TXD,TXDS); //module 头,verilog 95风格
input RXD; //输入信号
input RXCLK; //输入时钟
input RXSET; //输入的复位信号
output[7:0]TXD; //输出的数据,8bit
reg [7:0]TXD; //输出寄存器
output[2:0]TXDS; //输出信号
reg [2:0]TXDS; //输出寄存
output TXCLK; //输出的时钟
reg TXCLK; //输出时钟寄存
reg RXD_D1; //输入的数据寄存器。单比特
reg RXD_D2;
reg RXD_D3;
reg RXD_D4;
reg RXD_D5;
reg RXD_D6;
reg RXD_D7;
reg RXD_D8; //输入的数据寄存器。单比特
//在接收rxclk下,每个时候域接收rxd数据,寄存一级
always @(posedge RXCLK or negedge RXSET)
if(!RXSET)
RXD_D1<=1'b0;
else RXD_D1<=RXD;
//在接收rxclk下,每个时候域接收rxd数据,寄存二级,即打两拍
always @(posedge RXCLK or negedge RXSET)
if(!RXSET)
RXD_D2<=1'b0;
else RXD_D2<=RXD_D1;
//寄存三级,即打三拍
always @(posedge RXCLK or negedge RXSET)
if(!RXSET)
RXD_D3<=1'b0;
else RXD_D3<=RXD_D2;
always @(posedge RXCLK or negedge RXSET)
if(!RXSET)
RXD_D4<=1'b0;
else RXD_D4<=RXD_D3;
always @(posedge RXCLK or negedge RXSET)
if(!RXSET)
RXD_D5<=1'b0;
else RXD_D5<=RXD_D4;
always @(posedge RXCLK or negedge RXSET)
if(!RXSET)
RXD_D6<=1'b0;
else RXD_D6<=RXD_D5;
always @(posedge RXCLK or negedge RXSET)
if(!RXSET)
RXD_D7<=1'b0;
else RXD_D7<=RXD_D6;
//寄存8级,即打8拍,
always @(posedge RXCLK or negedge RXSET)
if(!RXSET)
RXD_D8<=1'b0;
else RXD_D8<=RXD_D7;
///////////////////////////////////////////////////////////////////
////////////////////search for 01111110 indacation/////////////////
///////////////////////////////////////////////////////////////////
reg [2:0]l_cs,l_ns; //定义2个3bit的状态信号,当前态l_cs,下一个状态l_ns
//3bit的原因在于需要选择的数据为0~7,只需3bit
parameter s_hunt=3'd0,s0=3'd1,s1=3'd2,s2=3'd3,s3=3'd4,s4=3'd5,s5=3'd6,s6=3'd7;
//定义初始态s_hunt=0’
//否则选择将下一个状态l_ns赋给当前态l_cs
always @(posedge RXCLK or negedge RXSET)
if(!RXSET)
l_cs<=s_hunt;
else l_cs<=l_ns;
//下面的状态机用于寻找序列"0111111"
//如果找到当前的要寻找的输入数,则跳入到下一个状态,否则跳到s0态,开始新一轮的寻找,
//通过这种方法寻找到所需要的序列“01111110”
always @(l_cs or RXD)
case(l_cs)
s_hunt:begin
if(RXD==1'b0)
l_ns=s0;
else l_ns=s_idle;
end
s0:begin
if(RXD==1'b1)
l_ns=s1;
else l_ns=s0;
end
s1:begin
if(RXD==1'b1)
l_ns=s2;
else l_ns=s0;
end
s2:begin
if(RXD==1'b1)
l_ns=s3;
else l_ns=s0;
end
s3:begin
if(RXD==1'b1)
l_ns=s4;
else l_ns=s0;
end
s4:begin
if(RXD==1'b1)
l_ns=s5;
else l_ns=s0;
end
s5:begin
if(RXD==1'b1)
l_ns=s6;
else l_ns=s0;
end
s6:l_ns=s_idle;
endcase
//定义了寄存器SE_ind,
//该部分逻辑为组合逻辑,当找到所需要找的序列“01111110”时,输出SE_ind为1,否则为0;
//该信号相当于一个指示信号。是否找到所需的序列
reg SE_ind;
always @(l_cs or RXD)
if(l_cs==s6 && RXD==1'b0)
SE_ind=1'b1;
else SE_ind=1'b0;
代码中,step1和step2,分别是一个五进制的计数器,step1是由时钟的上升沿计数,step2是由时钟的下降沿计数的。step 1的最低位和step2的最低位波形如上图所示。上述两个信号进行或 *** 作输出clockout信号,也就是说clockout是clockin的五分频输出电路,占空比为50%。
这是一个任务。这个任务是用来设置置位信号拉高和拉低持续的时钟周期数。
@(posedge clk);是一个触发事件,即当clk上升沿时触发,其实该事件什么也没做,在这里只是起了一个时钟周期延迟的功能。
根据代码描述,意思就是初始时rst为高,6个时钟周期后(因为有6个时钟上升沿),rst拉低,持续3个时钟周期,该task就结束了。
希望能帮到你。
读懂一个Verilog工程代码主要通过以下方面:
1、区分好结构,一个工程是由基本的顶层、模块、约束等部分组成的,通常模块都是在顶层中逐一实例化,所以,了解一个工程的结构就是从顶层逐一向下延伸,相当于植物的根系,最底层的模块往往是被“引用”最多的,也是最基础的构成。
2、通过代码注释来辅助阅读,一段好的代码必须有70%~80%的注释,方便进行工作交接,以及多人讨论。重点通过代码结合注释,看懂工程师的意图,查找设计不严谨的地方。
3、verilog代码实际上就是在画电路图,是一种硬件描述语言,在读代码的同时,头脑中要有电路的概念,知道电路的大概结构是什么样的,每个模块的扇入扇出等。
当然,最基本的还是对语法和原理要有较好的基础,否则,很难看懂一些大规模的电路描述。
以上就是关于verilog 子程序解释全部的内容,包括:verilog 子程序解释、求verilogHDL语言大神,解释一下程序意思,最好能每行注释一下,感激不尽。、求这个verilog程序的各条语句的解释等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)