下面的代码我已经用modelsim仿真过了,没有问题。
module count(out,clk,rst); //源程序
input clk,rst;
output[3:0] out;
reg[3:0] out;
initial out=4'd0;
always @(posedge clk or negedge rst)
begin
if(!rst) out=4'd0;
else
begin
out=out+4'd1;
if(out==4'd1||out==4'd6||out==4'd8) out=out+4'd1;
if(out==4'd5) out=out+4'd2;
end
end
endmodule
`timescale 1ns/1ns //测试程序
`include "countv"
module count_tp;
reg clk,rst;
wire[3:0] out;
parameter DELY=100;
count mycount(out,clk,rst);
always #(DELY/2) clk=~clk;
initial
begin
clk=0;rst=1;
#(DELY5) rst=0;
#DELY rst=1;
#(DELY20) $finish;
end
initial $monitor($time,,,"clk=%d rst=%d out=%d",clk,rst,out);
endmodule
1
module sig2component(clk, rst_n, din, dout)
input clk;
input rst_n;
input [7:0] din;
output [7:0] dout;
always @ (posedge clk or negedge rst_n)
if (!rst_n)
dout <= 0;
else if (din[7]) begin
dout[6:0] <= ~din[6:0] + 7'd1;
dout[7] <= din[7];
end
else
dout <= din;
endmodule
2
module compare(clk, rst_n, din, flag_out)
input clk, rst_n;
input [3:0] din;
output flag_out;
always @ (posedge clk or negedge rst_n)
if (!rst_n)
flag_out <= 0;
else if (din > 4'd4)
flag_out <= 1'b1;
else
flag_out <= 1'b0;
module clk_div(clk,out1,out2);
input clk;
output out1,out2;
reg out1,out2;
reg [31:0]cnt1,cnt2;
always @(posedge clk)begin//50MHz分频计数
if(cnt1<32'd24999999)
cnt1 <=cnt1 + 32'd1;
else
cnt1 <=32'd0;
end
always @(posedge clk)//分频后的半周期反转
if(cnt1 == 0)
out1<=~out1;
always @(posedge clk)begin//5MHz分频计数
if(cnt2<32'd4999999)
cnt2 <=cnt2 + 32'd1;
else
cnt2 <=32'd0;
end
always @(posedge clk)//20%占空比
if(cnt2 == 32'd999999)
out2<=0;
else if(cnt2 == 32'd4999999)
out2<=1;
endmodule
假设你的clk就是1s周期的时钟
那么10s的应该是这么写
reg
[3:0]
cnt_10;
reg
clk_10s;
always
@
(posedge
rst
or
posedge
clk)
begin
if
(rst)
begin
cnt_10
<=
0;
clk_10s<=
0;
end
else
begin
if
(cnt_10==4)
begin
cnt_10
<=
0;
clk_10s<=~clk_10s;
end
else
begin
cnt_10
<=
cnt_10
+1;
clk_10s<=
clk_10s;
end
end
60的,cnt就在29归零,同时clk_60s反向
是在半周期反向才是占空比1:1。
always 不是循环语句,always 是一个进程块。 always@(A or B or C)我们经常能看到的always语句如上面那句,当括号里的A,B或C信号发生变化的时候,这个ALWAYS模块就被激活,模块中的语句才能执行。括号里的信号称之为敏感信号列表。 所有的ALWAYs块之间是并行的关系,谁在前谁在后不影响执行的顺序。
for 是一个循环语句,但是不可以综合(编译)。for通常是用在测试文件里面。或者用于对RAM附初值。比如定义了一个RAM空间
reg [N-1:0] mem [word-1:0];
初始化时可以用for循环
integer i;
for(i=0;i<word;i=i+1)
mem[i]<=0;
这样就把RAM的内容全部定义为0了。但是FOR不能用在电路实体中。
VERILOG是硬件描述语言,用来描述硬件的结构和行为,不是软件,不是C语言,有很大的不同,没有循环这种说法。可以说VERILOG做的程序实际和硬件工程师画图是一回事,每个语句,每个模块,表示的是使用了一块芯片,然后连上线这样,硬件电路哪儿来的循环一说,要注意好好区别。
module voter7(pass,vote) ;
input [7:1] vote;
output pass
reg[2:0] sum;
integer i;
reg pass
always @ (vote)
begin
sum=0;
for (i=1 ; i〈=7 ; i=i+1)
if(vote[i])
sum=sum+1;
else
sum=sum;
if(sum[2])
pass=1;
else
pass=0
end
endmodule
原来的代码实在无力吐槽。我按照开发者的意思重新修改了一下,你可以试着再编译一下,如果再有问题可以找我。
这是一个七位表决器,vote信号是7位信号,当七个裁判中有超过3个人投肯定票的时候,sum信号就会变成二进制数2‘b100以上的数字,这时候其最高位sum[2]就会变成1,那么pass信号就输出1表示选手通过了投票。
对这个程序的开发理念我表示如下意见:
尽量不要使用for语句,for语句不可综合。
在使用if以后一定要加上else,即使else后面跟一个空语句也行,这样不容易产生不必要的锁存器。
七位表决器的话,前面可以加上一个前置锁存模块,防止裁判在投票之后误 *** 作导致结果出现变化,同时前置的锁存模块可以加入复位信号,使得表决器功能更为优化。
以上就是关于用verilog编写源代码和测试程序全部的内容,包括:用verilog编写源代码和测试程序、求Verilog HDL程序、用Verilog HDL编写简单的程序!数电实验!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)