【随笔】“真OO无双”前辈提供的SEG7_Controller模块的问题改进
首先,非常感謝“真OO無(wú)雙”前輩,在學(xué)習(xí)FPGA過程中給與了極大幫助。在此記錄一些問題,希望能幫助別人,也給自己留點(diǎn)記錄,方便以后查找。
????? 前輩在(原創(chuàng)) 如何設(shè)計(jì)一個(gè)七段顯示器Controller? 中給了出了一個(gè)例子,如下:
我的板子是DE3—150,上面有兩顆數(shù)碼管。將其作為自定義組建加入到SOPC Builder中(具體參考(原創(chuàng)) 如何設(shè)計(jì)一個(gè)七段顯示器Controller? ),其參數(shù)修改為:
?
1 module SEG7_Controller (2 // Avalon clock interface siganals
3 ? input csi_clockreset_clk,
4 input csi_clockreset_reset_n,
5 // Signals for Avalon-MM slave port
6 ? input [ADDR_WIDTH-1:0] avs_s1_address,
7 input avs_s1_write,
8 input [DATA_WIDTH-1:0] avs_s1_writedata,
9 // user logic inputs and outputs
10 ? output [SEG7_NUM*8-1:0] avs_s1_export_oHEX
11 );
12
13 parameter DATA_WIDTH = 32; // data bus width
14 ?parameter SEG7_NUM = 8; // specify the number of seg7 unit
15 ?parameter ADDR_WIDTH = 3; // log2(SEG7_NUM)
16 ?
17 reg [SEG7_NUM-1:0] base_index;
18 reg [DATA_WIDTH-1:0] write_data;
19 reg [(SEG7_NUM*8-1):0] reg_file;
20
21 assign avs_s1_export_oHEX = ~reg_file;
22
23 always@(posedge csi_clockreset_clk, negedge csi_clockreset_reset_n) begin
24 if (!csi_clockreset_reset_n) begin
25 integer i;
26 base_index <= 8'h00;
27 write_data <= 8'h00;
28
29 for(i = 0; i < SEG7_NUM * 8; i = i + 1)
30 reg_file[i] <= 1'b1;
31 end
32 else begin
33 if (avs_s1_write) begin
34 integer j;
35 write_data <= avs_s1_writedata;
36 base_index <= (avs_s1_address << 3);
37
38 for(j = 0; j < 8; j = j + 1)
39 reg_file[base_index+j] <= write_data[j];
40 end
41 end
42 end
43
44 endmodule
?
?
?
SEG7_NUM = 2;ADDR_WIDTH = 1;
?
編譯下載到板子上,然后在Nios II中運(yùn)行測(cè)試程序,在低位向高位進(jìn)位時(shí)出現(xiàn)錯(cuò)誤現(xiàn)象:
...08—>09—>00—>11—>12...19—>10—>21...
也就是說,低位向高位進(jìn)位時(shí),低位清零,高位沒變化,下一次更新時(shí),高低位一起更新。
分析代碼33~39行,由于使用阻塞賦值,reg_file,base_index以及write_data中的數(shù)據(jù)其實(shí)都是前一時(shí)鐘周期的,那么其中數(shù)值變化如下:
?。
修改代碼如下,問題解決。
?
1 module SEG7_Controller (2 // Avalon clock interface siganals
3 input csi_clockreset_clk,
4 input csi_clockreset_reset_n,
5 // Signals for Avalon-MM slave port
6 input [ADDR_WIDTH-1:0] avs_s1_address,
7 input avs_s1_write,
8 input [31:0] avs_s1_writedata,
9 // user logic inputs and outputs
10 output [SEG7_NUM*8-1:0] avs_s1_export_oHEX
11 );
12
13 parameter SEG7_NUM = 8; // specify the number of seg7 unit
14 parameter ADDR_WIDTH = 3; // log2(SEG7_NUM)
15 parameter DEFAULT_ACTIVE = 1;
16 parameter LOW_ACTIVE = 1;
17
18 reg [(SEG7_NUM*8-1):0] reg_file;
19
20 assign avs_s1_export_oHEX = (LOW_ACTIVE)?~reg_file:reg_file;
21
22 always@(posedge csi_clockreset_clk, negedge csi_clockreset_reset_n) begin
23 if (!csi_clockreset_reset_n) begin
24 reg_file[(SEG7_NUM*8-1):0] <= (DEFAULT_ACTIVE)?8'hFF:8'h00; // trun on or off
25 end
26 else begin
27 if (avs_s1_write) begin
28 integer j;
29 for(j = 0; j < 8; j = j + 1)
30 reg_file[(avs_s1_address << 3) + j] <= avs_s1_writedata[j];
31 // reg_file[((avs_s1_address << 3) + 7 ):(avs_s1_address << 3)] <= avs_s1_writedata[7:0];
32 end
33 end
34 end
35
36 endmodule
?
?
方法二,還可以在起另外一個(gè)always塊,在其中完成write_data對(duì)reg_file的賦值,因?yàn)閏lk非常快,不受avs_s1_write信號(hào)控制,可以避免此情況。
?
總結(jié):
- reg變量,相當(dāng)于觸發(fā)器,若采用阻塞賦值,傳遞出去的其實(shí)是其存放的前一時(shí)鐘周期的值。
- 制作自定義組建時(shí),對(duì)寄存器的讀寫,應(yīng)該與寄存器功能實(shí)現(xiàn)分開,如方法2.?
?
?
?
?
?
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/xiyi/archive/2010/11/03/1868427.html
總結(jié)
以上是生活随笔為你收集整理的【随笔】“真OO无双”前辈提供的SEG7_Controller模块的问题改进的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 幼儿绘本故事教案一等奖
- 下一篇: 探访森林幼儿园