续第3章“1位SMG控制器”,从这个基础上,建立一个“4位的SMG控制器”。
“4位SMG控制器”的构思也依然简单。就是利用状态机以固定的次序发送每一位“数码管码”和“选码来”来达到扫描的效果。
注意点
从示意图中,可以清楚的看见“SPI Controller”有输入的痕迹。经前几章的实验,“SPI控制器”的设计是个体的,如今多了“SMG_Code”(数码管码输入)和“Row_Code"(位选码输入)。
1.module smg_controller
2.(
3. CLK, RST, SCL, SDO, STCP
4.);
5.
6. input CLK;
7. input RST;
8. output SCL, SDO, STCP;
9.
10. /*****************************************/
11.
12. //SMG code
13. parameter _0 = 7'h3f, _1 = 7'h06, _2 = 7'h5b, _3 = 7'h4f, _4 = 7'h66;
14.
15. //Row scan code
16. parameter _R1 = 8'b1111_0111,
17. _R2 = 8'b1111_1011,
18. _R3 = 8'b1111_1101,
19. _R4 = 8'b1111_1110;
20.
21. /*****************************************/
22.
23. //state mechine parameter
24. parameter R1 = 4'd1, R2 = 4'd2, R3 = 4'd3, R4 = 4'd4;
25.
26. /*****************************************/
27.
28. reg [7:0]rSMG;
29. reg [7:0]rRow;
30. reg [3:0]Current;
31. reg [3:0]Next;
32.
33. always @ ( posedge CLK or negedge RST )
34. if( !RST )
35. begin
36. Current <= R1;
37. end
38. else
39. Current <= Next;
40.
41. always @ ( posedge CLK or negedge RST )
42. if( !RST )
43. begin
44. Next <= R1;
45. rSMG <= 8'd0;
46. rRow <= 8'd0;
47. end
48. else
49. case ( Current )
50.
51. R1 : //scan row1
52. begin
53. rSMG <= _1; rRow <=_R1;
54. //each active low of STCP, end of one row scaning.
55. if( !STCP ) Next <= R2;
56. else Next <= R1;
57. end
58.
59. R2 : //scan row2
60. begin
61. rSMG <= _2; rRow <=_R2;
62. if( !STCP ) Next <= R3;
63. else Next <= R2;
64. end
65.
66. R3 : //scan row3
67. begin
68. rSMG <= _3; rRow <=_R3;
69. if( !STCP ) Next <= R4;
70. else Next <= R3;
71. end
72.
73. R4 : //scan row4
74. begin
75. rSMG <= _4; rRow <=_R4;
76. if( !STCP ) Next <= R1;
77. else Next <= R4;
78. end
79.
80. endcase
81.
82. /************************************************/
83.
84. wire Done_Sig;
85. wire Send_Sig;
86. wire [7:0]DI;
87.
88. //construct module
89.
90. spi_controller u1
91. (
92. .SMG_Code( rSMG ), // in - link in to u1
93. .Row_Code( rRow ), // in - link in to u1
94. .CLK( CLK ), // in - global link in
95. .RST( RST ), // in - global link in
96. .STCP( STCP ), // out - global link out
97. .Done_Sig( Done_Sig ), // in - u2 link to u1
98. .Send_Sig( Send_Sig ), // out - u1 link to u2
99. .DI( DI ) // out - u1 link to u2
100. );
101.
102. spi_module u2
103. (
104. .CLK( CLK ), // in - global link in
105. .RST( RST ), // in - global link in
106. .Done_Sig( Done_Sig ), // out - u2 link to u1
107. .Send_Sig( Send_Sig ), // in - u1 link to u2
108. .DI( DI ), // in - u1 link to u2
109. .SDO( SDO ), //global link out
110. .SCL( SCL ) //global link out
111. );
112.
113.endmodule
经修改的SPI控制器Verilog 代码:
1.module spi_controller
2.(
3. SMG_Code, Row_Code,
4. RST, CLK, Send_Sig, Done_Sig, DI, STCP
5.);
6.
7. input RST;
8. input CLK;
9. input Done_Sig;
10. input [7:0]SMG_Code;
11. input [7:0]Row_Code;
12. output [7:0]DI;
13. output Send_Sig;
14. output STCP;
15.
16. /*****************************************/
17.
18. parameter D1 = 4'd1, R1 = 4'd2, STa = 4'd3, STb = 4'd4;
19.
20. /*****************************************/
21.
22. reg [3:0]Current;
23. reg [3:0]Next;
24. reg [7:0]rData;
25. reg rSTCP;
26. reg isSend;
27.
28. always @ ( posedge CLK or negedge RST )
29. if( !RST )
30. Current <= D1;
31. else
32. Current <= Next;
33. always @ ( posedge CLK or negedge RST )
34. if( !RST )
35. begin
36. Next <= D1;
37. isSend <= 0;
38. rData <= 8'd0;
39. rSTCP <= 1'b1;
40. end
41. else
42. case ( Current )
43.
44. D1 :
45. begin
46. isSend <= 1; rData <= SMG_Code;
47. if( Done_Sig ) begin isSend <= 1'b0; Next <= R1; end
48. else Next <= D1;
49. end
50.
51. R1 :
52. begin
53. isSend <= 1; rData <= Row_Code;
54. if( Done_Sig ) begin isSend <= 1'b0; Next <= STa; end
55. else Next <= R1;
56. end
57.
58. STa :
59. begin
60. rSTCP <= 1'b0;
61. Next <= STb;
62. end
63.
64. STb :
65. begin
66. rSTCP <= 1'b1;
67. Next <= D1;
68. end
69.
70. endcase
71.
72. assign STCP = rSTCP;
73. assign DI = rData;
74. assign Send_Sig = isSend;
75.
76. /*****************************************/
77.endmodule
1. 我们先来说说经修改的SPI控制器Verilog 代码。主要是第1~14行的声明修改了,多了
“SMG_Code”和“Row Code”(第3, 10, 11行)。然后就是46行和53行,“rData <= ”
右边赋值操作被修改了。
2. 现在把焦点放在smg_controller上。第1~9行是熟悉的声明。
3. 第49行到80行是关键,在24行定义了4个状态R1, R2, R3, R4,正如字面上的意思:位选1
到位选4。在R1状态的时候,“rSMG”和“rRow”数据寄存器均都被赋值(53行)。然
后检查“STCP信号”是否为低电平?如果是低电平,那么进入下一个状态“R2”(55
行),否则就一直停在同一个状态。(56行)
在R2状态的时候,“rSMG”和“rRow”数据寄存器均都被赋值(61行)。然后检查
“STCP信号”是否 为低电平?如果是低电平,那么进入下一个状态“R3”(62行),否
则就一直停在同一个状态。(63行)
在R3状态的时候,“rSMG”和“rRow”数据寄存器均都被赋值(68行)。然后检查 “STCP信号”是否 为低电平?如果是低电平,那么进入下一个状态“R4”(69行),否则
就一直停在同一个状态。(70行)
在R4状态的时候,“rSMG”和“rRow”数据寄存器均都被赋值(75行)。然后检查
“STCP信号”是否为低电平?如果是低电平,那么进入下一个状态“R1”(76行),否则
就一直停在同一个状态。(77行)
4. 我们知道当“SPI控制器”发送完16为的数据后(一字节“数码管码”和一字节“位选
码”),都会拉低“STCP信号”(SPI控制器代码第44~68行)。故此“SPI控制器”被
模块化后(90~100行),STCP引脚被引出致TOP模块(96行),我们就是利用这点来简
化设计。
问1: 我察觉了一个奇怪点?如常看特权的视频教程,TOP模块的建立都仅将模块好部分组织
起来,很明显你的设计有点不同。
答:这个问题问得很好!我这样做事为了方便设计,但是实际上在编译的时候会被警告。如
果你真的看不顺眼那个警告,可以模仿视频教程里的那样,利用TOP模块将全部以模块
好的部分组织起来。
问2: “rSMG”和“rRow”数据寄存器都是固定的吗?
答:“rRow”数据寄存器的赋值是固定的,而“rSMG”数据寄存器的赋值可以“随意”。
这一章没有仿真 m( 囧 )m 。
目前已经是建立第3层的模块了,后续还有。不过在这一阶段,必须理解一个道理,底层的模块与顶层的模块是不相干在工作,最多就是底层模块给顶层模块反馈信息。“4位SMG控制器”和“1位SMG控制器”区别就是在于“数码管的扫描位数”,设计都是大同小异。
这一章的实验可以直接下载到学习版看看!从板子的数码管上,自左向右会出现“4321”的数字。
https://static.assets-stash.eet-china.com/album/old-resources/2010/5/17/106f0428-a07b-47ff-ba88-2d557447723a.rar
用户410992 2011-10-26 18:27
用户1373959 2010-5-18 21:31