我所设计的是一个四位流水灯,每一位相当于一级,高一级灯亮与否由第一级控制。(串行设计思想:高级输入由低级输出控制)因此,我们所需要建立的模块有两个:
(1)、基本模块,即编写一个一位流水灯;
(2)、顶层模块,四位流水灯就要调用四次基本模块,当然,高一级的输入由第一级的输出控制。
(3)、编写testbench,仿真顶层模块,看功能是否正确实现;
当然,建模过程中,错误百出,都是一遍遍仿真,依据仿真波形,查找错误并改正,再仿真波形,查找错误(语法错误,逻辑错误等),以此循环,直到得到满意的结果。只是深感这种方法很浪费时间,但是作为暂处于初级学习阶段的菜鸟,找不到别的方法啊!!!下面还是进入正题吧:
1、一位流水灯设计:
module led1_module(clock,reset,Led_Out);
input clock,reset;
output Led_Out;
reg [7:0]count;
reg rLed_out;
always @(posedge clock,negedge reset)
if(!reset)
count<=8'd0;
else if (count==8'd42)
count<=8'd0;
else
count<=count+8'd1;
//上面条件控制语句,还真只能写出(count==8'd42),尽管我是希望四位流水灯的时钟周期是#400,那么count由0计数到39就可以了,但事与愿违,看看下面的仿真波形吧,由下面第一个图可发现0001->0010->0100->1000的每次跳变过程中,都出现了一个时钟的延时,因此,一整个周期变成了#430,所以count要由0计数到42才可以。
//把上面这个仿真波形放大了可发现,跳变过程中出现的一个时钟的延迟也相当于一个清零的过程,如下图所示。高一级的rst由第一级的输出控制,当低一级的输出由1变成0以后,高一级的输出清零,count也清零,然后再在下一个上升沿到来时,count才开始计算,高一级的输出由0变成1;因此,这种低级输出控制高级rst的方法,总会出现一个时钟的清零现象。
always @(posedge clock,negedge reset)
if(!reset)
rLed_out<=1'd0;
else if(count>=8'd0&&count<8'd10)
rLed_out<=1'd1;
else
rLed_out<=1'd0;
//在上面这个always过程块中,如果我将if(!reset) rLed_out<=1'd1;出现的仿真结果如下:虽然没有一个时钟延时,但明显逻辑错误。
assign Led_Out=rLed_out;
endmodule
2、顶层模块的设计:
`include "led1_module.v"
module mux_top_mudule(CLK,Rst,LED_OUT);
input CLK,Rst;
output [3:0]LED_OUT;
led1_module led1(CLK,Rst,LED_OUT[0]);
led1_module led2(CLK,~LED_OUT[0],LED_OUT[1]);
led1_module led3(CLK,~LED_OUT[1],LED_OUT[2]);
led1_module led4(CLK,~LED_OUT[2],LED_OUT[3]);
endmodule
//仿真过程中,出现过如下图错误。好吧,这个错完全是逻辑错误,因为,我在顶层模块这种写成:
led1_module led1(CLK,Rst,LED_OUT[0]);
led1_module led2(CLK,LED_OUT[0],LED_OUT[1]);
led1_module led3(CLK,LED_OUT[1],LED_OUT[2]);
led1_module led4(CLK,LED_OUT[2],LED_OUT[3]);
//另外,还是要注output为wire或reg类型的设置吧。例如在上面这个模块中,我开始设定了”reg LED_OUT“,结果编译没事,但不能仿真。因为,低一级的输出是高一级的rst输入,因此低一级的输出肯定要为wire类型,即LED_OUT[0]~LED_OUT[3]都为wire类型,但我开始申明了他们都是reg类型,必出错。这个问题还是很值得注意的,毕竟我昨天也犯了类似的错误,只是这个错是出现在顶层模块中,我将output定义成reg类型,但是仿真模块中,我定义为wire类型,两者类型不匹配。