数码管实验——简易秒表
秒表的制作并非一帆风顺,中间遇到了许多问题
比如计数寄存器的位数设置
reg [?:0] c1;
参考别人的代码写为31了,虽然最后成功了,但却不知道原因。。。
基础Verilog知识还是有待学习啊~‘
最终代码:
//======================================================= // This code is generated by Terasic System Builder //======================================================= module myDT( //////////// CLOCK ////////// CLOCK_50, RSTn, //////////// LED ////////// LEDG, LEDR, //////////// SEG7 ////////// HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7 ); //======================================================= // PARAMETER declarations //======================================================= parameter _0 = 7'b100_000_0, _1 = 7'b111_100_1, _2= 7'b010_010_0, _3 = 7'b011_000_0, _4 = 7'b001_100_1, _5 = 7'b001_001_0, _6= 7'b000_001_0, _7 = 7'b111_100_0, _8 = 7'b000_000_0, _9 = 7'b001_000_0; //======================================================= // PORT declarations //======================================================= //////////// CLOCK ////////// input CLOCK_50; input RSTn; //////////// LED ////////// output [8:0] LEDG; output [17:0] LEDR; //////////// SEG7 ////////// output [6:0] HEX0; output [6:0] HEX1; output [6:0] HEX2; output [6:0] HEX3; output [6:0] HEX4; output [6:0] HEX5; output [6:0] HEX6; output [6:0] HEX7; //======================================================= // REG/WIRE declarations //======================================================= reg [31:0] C7; reg [31:0] C6; reg [31:0] C5; reg [31:0] C4; reg [31:0] C3; reg [31:0] C2; reg [31:0] C1; reg [31:0] C0; reg [6:0] rHEX0; reg [6:0] rHEX1; reg [6:0] rHEX2; reg [6:0] rHEX3; reg [6:0] rHEX4; reg [6:0] rHEX5; reg [6:0] rHEX6; reg [6:0] rHEX7; //======================================================= // Structural coding //======================================================= //----1MS定时器 parameter T1MS = 16'd49_999; reg [16:0] Count1; always@(posedge CLOCK_50 or negedge RSTn) if(!RSTn) Count1 <= 16'd0; else if(Count1 == T1MS) Count1 <= 16'd0; else Count1 <= Count1 + 16'd1; //----MS定时器 reg [16:0] Count_MS; always@(posedge CLOCK_50 or negedge RSTn) if(!RSTn) Count_MS <= 16'd0; else if(Count_MS == 10'd1000) Count_MS <= 16'd0; else if(Count1 == T1MS) Count_MS <= Count_MS + 16'd1; //----S定时器 reg [16:0] Count_S; always@(posedge CLOCK_50 or negedge RSTn) if(!RSTn) Count_S <= 16'd0; else if(Count_S == 10'd60) Count_S <= 16'd0; else if(Count_MS == 16'd1000) Count_S <= Count_S + 16'd1; //----M定时器 reg [16:0] Count_M; always@(posedge CLOCK_50 or negedge RSTn) if(!RSTn) Count_M <= 16'd0; else if(Count_M == 10'd60) Count_M <= 16'd0; else if(Count_S == 10'd60) Count_M <= Count_M + 16'd1; //----数码管显示 always @ (posedge CLOCK_50 or negedge RSTn) if(!RSTn) begin C7 = 31'd0; C6 = 31'd0; C5 = 31'd0; C4 = 31'd0; C3 = 31'd0; C2 = 31'd0; C1 = 31'd0; C0 = 31'd0; end else begin C7 = Count_M/10; C6 = Count_M%10; C5 = Count_S/10; C4 = Count_S%10; C3 = Count_MS/1000; C2 = Count_MS/100%10; C1 = Count_MS%100/10; C0 = Count_MS%10; end always @ (posedge CLOCK_50 or negedge RSTn) case(C7) 0 : rHEX7 = _0; 1 : rHEX7 = _1; 2 : rHEX7 = _2; 3 : rHEX7 = _3; 4 : rHEX7 = _4; 5 : rHEX7 = _5; 6 : rHEX7 = _6; 7 : rHEX7 = _7; 8 : rHEX7 = _8; 9 : rHEX7 = _9; endcase always @ (posedge CLOCK_50 or negedge RSTn) case(C6) 0 : rHEX6 = _0; 1 : rHEX6 = _1; 2 : rHEX6 = _2; 3 : rHEX6 = _3; 4 : rHEX6 = _4; 5 : rHEX6 = _5; 6 : rHEX6 = _6; 7 : rHEX6 = _7; 8 : rHEX6 = _8; 9 : rHEX6 = _9; endcase always @ (posedge CLOCK_50 or negedge RSTn) case(C5) 0 : rHEX5 = _0; 1 : rHEX5 = _1; 2 : rHEX5 = _2; 3 : rHEX5 = _3; 4 : rHEX5 = _4; 5 : rHEX5 = _5; 6 : rHEX5 = _6; 7 : rHEX5 = _7; 8 : rHEX5 = _8; 9 : rHEX5 = _9; endcase always @ (posedge CLOCK_50 or negedge RSTn) case(C4) 0 : rHEX4 = _0; 1 : rHEX4 = _1; 2 : rHEX4 = _2; 3 : rHEX4 = _3; 4 : rHEX4 = _4; 5 : rHEX4 = _5; 6 : rHEX4 = _6; 7 : rHEX4 = _7; 8 : rHEX4 = _8; 9 : rHEX4 = _9; endcase
//尝试过加入这部分,但由于变化速度太快,视觉暂留什么的就导致后面4个数码管全部显示为8 /* always @ (posedge CLOCK_50 or negedge RSTn) case(C3) 0 : rHEX3 = _0; 1 : rHEX3 = _1; 2 : rHEX3 = _2; 3 : rHEX3 = _3; 4 : rHEX3 = _4; 5 : rHEX3 = _5; 6 : rHEX3 = _6; 7 : rHEX3 = _7; 8 : rHEX3 = _8; 9 : rHEX3 = _9; endcase always @ (posedge CLOCK_50 or negedge RSTn) case(C2) 0 : rHEX2 = _0; 1 : rHEX2 = _1; 2 : rHEX2 = _2; 3 : rHEX2 = _3; 4 : rHEX2 = _4; 5 : rHEX2 = _5; 6 : rHEX2 = _6; 7 : rHEX2 = _7; 8 : rHEX2 = _8; 9 : rHEX2 = _9; endcase always @ (posedge CLOCK_50 or negedge RSTn) case(C1) 0 : rHEX1 = _0; 1 : rHEX1 = _1; 2 : rHEX1 = _2; 3 : rHEX1 = _3; 4 : rHEX1 = _4; 5 : rHEX1 = _5; 6 : rHEX1 = _6; 7 : rHEX1 = _7; 8 : rHEX1 = _8; 9 : rHEX1 = _9; endcase always @ (posedge CLOCK_50 or negedge RSTn) case(C0) 0 : rHEX0 = _0; 1 : rHEX0 = _1; 2 : rHEX0 = _2; 3 : rHEX0 = _3; 4 : rHEX0 = _4; 5 : rHEX0 = _5; 6 : rHEX0 = _6; 7 : rHEX0 = _7; 8 : rHEX0 = _8; 9 : rHEX0 = _9; endcase */ //输出赋值 /*assign HEX0 = rHEX0; assign HEX1 = rHEX0; assign HEX2 = rHEX0; assign HEX3 = rHEX0; */ assign HEX0 = 7'b111_111_1; assign HEX1 = 7'b111_111_1; assign HEX2 = 7'b111_111_1; assign HEX3 = 7'b111_111_1; assign HEX4 = rHEX4; assign HEX5 = rHEX5; assign HEX6 = rHEX6; assign HEX7 = rHEX7; endmodule
总结:
1. 就算已经定义了输出量,比如input HEX7,后面always里面要用到的时候还是必须定义reg [6:0] rHEX7,而不能直接reg [6:0] HEX7
然后最后还必须要assign HEX7 = rHEX7
2. 之前always里面一口气写了8个case,虽然编译时没有语法错误,但烧到板子上却运行不出想要的效果。后来分开写,就好了,原因不详
3. DE2-115用的的晶振是50MHZ的,利用晶振~定时器的用法很巧妙丫——频率是指1秒内振动的次数,而振动一次计数器就加1,1ms需要振动的次数为 50MHZ*0.01s,然后就有 parameter T1MS=50MHZ*0.01s-1
4. 要习惯用parameter,这样可读性更高,而且方便
5. 关于计数器C1...reg的位数还有待进一步研究
学习硬件描述语言要用并行思维!并行思维!