赞
踩
6位8段数码管,低三位显示毫秒计数,最高位显示分钟,其余两位显示秒计数。
开始案件与暂停按键,复位按键直接全部归零。
扩展部分:每计满一次,led移位一次。
首先按键信号经过消抖再用,然后把产生的标志信号传给控制模块,由于控制逻辑很简单就把这部分控制逻辑放进“数据产生模块中了”;
然后把数码管与led接口模块interface放进去。
按理来讲,应该重新定义个接口模块再把led与nixie放进去,比较规范。
值得一提就是数据产生模块与数码管接口模块:
其实输出端口是几个级联得计数器。
代码奉上:
- `include "para.v"
- module data_gen (
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire start_flag ,
- input wire stop_flag ,
-
- output reg [3:0] po_data_one ,
- output reg [3:0] po_data_two ,
- output reg [3:0] po_data_thr ,
- output reg [3:0] po_data_fou ,
- output reg [3:0] po_data_fiv ,
- output reg [3:0] po_data_six ,
- output reg minute_flag
- );
- // localparam
- localparam IDLE = 3'b001 ,
- WORKING = 3'b010 ,
- STOP = 3'b100 ;
- // reg signal
- reg [15:0] cnt_1ms ;
- reg [2:0] state_c ;
- reg [2:0] state_n ;
- // wire signal
- wire add_cnt_1ms ;
- wire end_cnt_1ms ;
- wire IDLEtoWORKING ;
- wire WORKINGtoSTOP ;
- wire STOPtoWORKING ;
- /******************************************************************************************
- ********************************************main code**************************************
- *******************************************************************************************/
- // // reg signal
- // reg [2:0] state_c ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- state_c <= IDLE ;
- else
- state_c <= state_n ;
- end
- // reg [2:0] state_n ;
- always @(*) begin
- if(~sys_rst_n)
- state_n = IDLE ;
- else
- case(state_c)
- IDLE : if(IDLEtoWORKING)
- state_n = WORKING ;
- else
- state_n = IDLE ;
- WORKING: if(WORKINGtoSTOP)
- state_n = STOP ;
- else
- state_n = WORKING ;
- STOP : if(STOPtoWORKING)
- state_n = WORKING ;
- else
- state_n = STOP ;
- default: state_n = IDLE ;
- endcase
- end
- assign IDLEtoWORKING = (state_c == IDLE ) && (start_flag) ;
- assign WORKINGtoSTOP = (state_c == WORKING ) && (stop_flag ) ;
- assign STOPtoWORKING = (state_c == STOP ) && (start_flag) ;
- // reg [15:0] cnt_1ms ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- cnt_1ms <= 16'd0 ;
- else if(add_cnt_1ms) begin
- if(end_cnt_1ms)
- cnt_1ms <= 16'd0 ;
- else
- cnt_1ms <= cnt_1ms + 1'b1 ;
- end
- else if(state_c == IDLE)
- cnt_1ms <= 16'd0 ;
- else
- cnt_1ms <= cnt_1ms ;// 注意这里,是保持还是归零。
- end
- // wire add_cnt_1ms ;
- assign add_cnt_1ms = (state_c == WORKING ) ;
- // wire end_cnt_1ms ;
- assign end_cnt_1ms = add_cnt_1ms && (cnt_1ms == `MAX_CNT_1MS - 1) ;
- // output signal description
- // output reg [3:0] po_data_one ,
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- po_data_one <= 4'd0 ;
- else if(end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1)
- po_data_one <= 4'd0 ;
- else if(end_cnt_1ms)
- po_data_one <= po_data_one + 1'b1 ;
- else
- po_data_one <= po_data_one ;
- end
- // output reg [3:0] po_data_two ,
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- po_data_two <= 4'd0 ;
- else if((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)
- po_data_two <= 4'd0 ;
- else if(end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1)
- po_data_two <= po_data_two + 1'b1 ;
- else
- po_data_two <= po_data_two ;
- end
- // output reg [3:0] po_data_thr ,
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- po_data_thr <= 4'd0 ;
- else if((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1))
- po_data_thr <= 4'd0 ;
- else if(((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1))
- po_data_thr <= po_data_thr + 1'b1 ;
- else
- po_data_thr <= po_data_thr ;
- end
- // output reg [3:0] po_data_fou , 显示秒的个位 0 ~ 9
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- po_data_fou <= 4'd0 ;
- else if(((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1))
- po_data_fou <= 4'd0 ;
- else if((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1))
- po_data_fou <= po_data_fou + 1'b1 ;
- else
- po_data_fou <= po_data_fou ;
- end
- // output reg [3:0] po_data_fiv , 显示秒的十位 0 ~ 5
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- po_data_fiv <= 4'd0 ;
- else if(((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1) && (po_data_fiv == `MAX_CNT_NUM - 5))
- po_data_fiv <= 4'd0 ;
- else if(((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1))
- po_data_fiv <= po_data_fiv + 1'b1 ;
- else
- po_data_fiv <= po_data_fiv ;
- end
- // output reg [3:0] po_data_six ,
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- po_data_six <= 4'd0 ;
- else if((((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1) && (po_data_fiv == `MAX_CNT_NUM - 5)) && (po_data_six == `MAX_CNT_NUM - 1))
- po_data_six <= 4'd0 ;
- else if(((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1) && (po_data_fiv == `MAX_CNT_NUM - 5))
- po_data_six <= po_data_six + 1'b1 ;
- else
- po_data_six <= po_data_six ;
- end
- // reg minute_flag
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- minute_flag <= 1'b0 ;
- else if((((((end_cnt_1ms && po_data_one == `MAX_CNT_NUM - 1) && po_data_two == `MAX_CNT_NUM - 1)) && (po_data_thr == `MAX_CNT_NUM - 1)) && (po_data_fou == `MAX_CNT_NUM - 1) && (po_data_fiv == `MAX_CNT_NUM - 5)) && (po_data_six == `MAX_CNT_NUM - 1))
- minute_flag <= 1'b1 ;
- else
- minute_flag <= 1'b0 ;
- end
-
- endmodule
当复位按键按下,现态与次态都需要回到IDLE状态。
在代码层面,给state_n设置一个复位情况。
创新点,与以往不同的代码设计,这次用了“函数”,function。
代码奉上:
- `include "para.v"
- module nixie (
- input wire sys_clk ,
- input wire sys_rst_n ,
- input wire [3:0] pi_data_one ,
- input wire [3:0] pi_data_two ,
- input wire [3:0] pi_data_thr ,
- input wire [3:0] pi_data_fou ,
- input wire [3:0] pi_data_fiv ,
- input wire [3:0] pi_data_six ,
-
- output reg [5:0] sel ,
- output reg [7:0] dig
- );
- // reg
- reg dot ; // 数码管上的小数点。
- reg [31:0] cnt_time ; // 移位寄存器的移位时间,计数器。
- // wire
- wire add_cnt_time ;
- wire end_cnt_time ;
- /******************************************************************************************
- ********************************************main code**************************************
- *******************************************************************************************/
- // reg signal description
- // reg [31:0] cnt_time ; // 移位寄存器的移位时间。
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- cnt_time <= 32'd0 ;
- else if(add_cnt_time) begin
- if(end_cnt_time)
- cnt_time <= 32'd0 ;
- else
- cnt_time <= cnt_time + 1'b1 ;
- end
- else
- cnt_time <= 32'd0 ; // 注意这里,是保持还是归零。
- end
- // reg dot ;
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- dot <= 1'b1 ;
- else
- dot <= 1'b1 ;
- end
-
- // wire signal description
- assign add_cnt_time = 1'b1 ;
- assign end_cnt_time = add_cnt_time && (cnt_time == `MAX_CNT_TIES - 1) ;
- // task
- // task nixie_dig ;
- // input [3:0] data_num ;
- // output [7:0] po_dig ;
- // case (data_num)
- // 0 : po_dig = {dot, `ZERO } ;
- // 1 : po_dig = {dot, `ONE } ;
- // 2 : po_dig = {dot, `TWO } ;
- // 3 : po_dig = {dot, `THREE } ;
- // 4 : po_dig = {dot, `FOUR } ;
- // 5 : po_dig = {dot, `FIVE } ;
- // 6 : po_dig = {dot, `SIX } ;
- // 7 : po_dig = {dot, `SEVEN } ;
- // 8 : po_dig = {dot, `EIGHT } ;
- // 9 : po_dig = {dot, `NINE } ;
- // default: po_dig = 8'd0 ;
- // endcase
- // endtask
- // function
- function [6:0] dig_num;
- input [3:0] data_in ;
- case (data_in)
- 0 : dig_num = `ZERO ;
- 1 : dig_num = `ONE ;
- 2 : dig_num = `TWO ;
- 3 : dig_num = `THREE ;
- 4 : dig_num = `FOUR ;
- 5 : dig_num = `FIVE ;
- 6 : dig_num = `SIX ;
- 7 : dig_num = `SEVEN ;
- 8 : dig_num = `EIGHT ;
- 9 : dig_num = `NINE ;
- default: dig_num = 7'd0 ;
- endcase
- endfunction
- // Output signal description
- // output reg [5:0] sel ,
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- sel <= 6'b111_110 ;
- else if(end_cnt_time)
- sel <= {sel[4:0],sel[5]} ;
- else
- sel <= sel ;
- end
- // output reg [7:0] dig
- always @(posedge sys_clk or negedge sys_rst_n) begin
- if(~sys_rst_n)
- dig <= 8'd0 ;
- else
- case (sel)
- 6'b111_110: dig <= {dot, dig_num(pi_data_one)} ;
- 6'b111_101: dig <= {dot, dig_num(pi_data_two)} ;
- 6'b111_011: dig <= {dot, dig_num(pi_data_thr)} ;
- 6'b110_111: dig <= {1'b0, dig_num(pi_data_fou)} ;
- 6'b101_111: dig <= {dot, dig_num(pi_data_fiv)} ;
- 6'b011_111: dig <= {1'b0, dig_num(pi_data_six)} ;
- default : dig <= {dot, `SIX } ;
- endcase
- end
- endmodule
函数或者任务的使用,是使得代码写起来更方便,设计起来更节省时间。
减少重复劳动。
要灵活使用。多观察,多分析,多获取信息。找到相关性,相似性。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。