4.1建
立2个“低级功能模块”
“ 自左向右循环3次,自右向左循环5次,然后自左向右一次,自右向左一次,然后自左向右循环30次 ”
假设这是实验的要求, 首先我们先建立两个“低级功能模块”。一个名为flashing_to_left 和 flashing_to_right 。
1.module flashing_to_right
2.(
3. CLK, RSTn,
4. Start_Sig, Done_Sig,
5. Q
6.);
7.
8. input CLK;
9. input RSTn;
10. input Start_Sig;
11. output Done_Sig;
12. output [7:0]Q;
13.
14. /***********************************/
15.
16. parameter DELAY = 8'd200;
17.
18. /***********************************/
19.
20. reg [7:0]Counter;
21.
22. always @ ( posedge CLK or negedge RSTn )
23. if( !RSTn )
24. Counter <= 8'd0;
25. else if( Counter == DELAY )
26. Counter <= 8'd0;
27. else if( Start_Sig )
28. Counter <= Counter + 1'b1;
29. else
30. Counter <= 8'd0;
31.
32. /***************************************/
33.
34. reg [3:0]i;
35. reg [7:0]rData;
36. reg isDone;
37.
38. always @ ( posedge CLK or negedge RSTn )
39. if( !RSTn )
40. begin
41. i <= 4'd0;
42. isDone <= 1'b0;
43. rData <= 8'dx;
44. end
45. else if( Start_Sig )
46. case( i )
47.
48. 4'd0 :
49. begin rData <= 8'dx; i <= i + 1'b1; end
50.
51. 4'd1, 4'd2, 4'd3, 4'd4, 4'd5, 4'd6, 4'd7, 4'd8 :
52. if( Counter == DELAY ) i <= i + 1'b1;
53. else rData <= ( 8'h80 >> i - 1 );
54.
55. 4'd9 :
56. begin i <= 4'd10; isDone <= 1'b1; end
57.
58. 4'd10 :
59. begin i <= 4'd0; isDone <= 1'b0; end
60.
61. endcase
62.
63.
64. /**********************************/
65.
66. assign Done_Sig = isDone;
67. assign Q = ( i > 0 && i < 9 ) ? rData : 8'dx;
68.
69. /**********************************/
70.
71.endmodule
1.module flashing_to_left
2.(
3. CLK, RSTn,
4. Start_Sig, Done_Sig,
5. Q
6.);
7.
8. input CLK;
9. input RSTn;
10. input Start_Sig;
11. output Done_Sig;
12. output [7:0]Q;
13.
14. /***********************************/
15.
16. parameter DELAY = 8'd200;
17.
18. /***********************************/
19.
20. reg [7:0]Counter;
21.
22. always @ ( posedge CLK or negedge RSTn )
23. if( !RSTn )
24. Counter <= 8'd0;
25. else if( Counter == DELAY )
26. Counter <= 8'd0;
27. else if( Start_Sig )
28. Counter <= Counter + 1'b1;
29. else
30. Counter <= 8'd0;
31.
32. /***************************************/
33.
34. reg [3:0]i;
35. reg [7:0]rData;
36. reg isDone;
37.
38. always @ ( posedge CLK or negedge RSTn )
39. if( !RSTn )
40. begin
41. i <= 4'd0;
42. isDone <= 1'b0;
43. rData <= 8'dx;
44. end
45. else if( Start_Sig )
46. case( i )
47.
48. 4'd0 :
49. begin rData <= 8'dx; i <= i + 1'b1; end
50.
51. 4'd1, 4'd2, 4'd3, 4'd4, 4'd5, 4'd6, 4'd7, 4'd8 :
52. if( Counter == DELAY ) i <= i + 1'b1;
53. else rData <= ( 8'h01 << i - 1 );
54.
55. 4'd9 :
56. begin i <= 4'd10; isDone <= 1'b1; end
57.
58. 4'd10 :
59. begin i <= 4'd0; isDone <= 1'b0; end
60.
61. endcase
62.
63. /**********************************/
64.
65. assign Done_Sig = isDone;
66. assign Q = ( i > 0 && i < 9 ) ? rData : 8'dx;
67.
68. /**********************************/
69.
70.endmodule
两
个模块几乎是一模一样,不同的地方只是在 53行而已。虽然代码都很简单,但是还是稍微关心 45 ~ 61 行的代码,因为是功能的核心部分。正如模板结构般,在第45行,如果Start_Sig 不处于高电平,那么该模块根本无法执行功能。计数寄存器i使用与指向下一个步骤,正如在第49行,当rData 被初始化过后,i指向下一个步骤。
在51行到53行之间,是移位操作,每一次的移位动作都需要200个时钟周期。移位操作一共有8个步骤。最后该模块产生一个“高脉冲”以表示“完成”,然而i也被复位为0。
仿真效果如下
点击浏览下一页
(第一行是输出Q,第二行是Start_Sig,第三行是完成信号)
( 最后一行是完成信号 )
点击浏览下一页
注意最后一行,当i 计数从1~8过后,就产生一个完成信号,而完成信号需要两个时钟周期的时间。
完成创建2个“低级功能模块”以后,为了使日后调用方便,必须封装起来。“低级功能模块”的封装工作会比较麻烦,因为“低级功能模块”有“复用连线”的现象,换一句话说,会出现“两义性”或者“多义性”的问题 ...... |