[原创].七段数码管驱动,Verilog版本
生活随笔
收集整理的這篇文章主要介紹了
[原创].七段数码管驱动,Verilog版本
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
我以前在艾米電子寫的驅動。貼在博客之目的:一、時常記記,以防忘記;二、分享給大家。也許是工作比較忙之緣故吧,新近的博文啰嗦的話語少了許多,直接貼上代碼,大家有什么不明白的,留言即可。
版本1
頂層例化文件
module seg7x8(input CLOCK_50, // 板載50MHz時鐘 input Q_KEY, // 板載按鍵RSToutput [7:0] SEG7_SEG, // 七段數碼管 段腳 output [2:0] SEG7_SEL // 七段數碼管 待譯位腳 );// 顯示效果: // ------------------------- // |1 |2.|3 |4 | |B |C |D | // ------------------------- seg7x8_drive u0(.i_clk (CLOCK_50),.i_rst_n (Q_KEY),.i_turn_off (8'b0000_1000), // 熄滅位[2進制][此處取第3位.i_dp (8'b0100_0000), // 小數點位[2進制][此處取第6位.i_data (32'h1234_ABCD), // 欲顯數據[16進制].o_seg(SEG7_SEG),.o_sel(SEG7_SEL) );endmodule驅動文件
module seg7x8_drive(input i_clk,input i_rst_n,input [7:0] i_turn_off, // 熄滅位[2進制input [7:0] i_dp, // 小數點位[2進制input [31:0] i_data, // 欲顯數據[16進制 output [7:0] o_seg, // 段腳output [2:0] o_sel // 使用74HC138譯出位腳 );//++++++++++++++++++++++++++++++++++++++ // 分頻部分 開始 //++++++++++++++++++++++++++++++++++++++ reg [16:0] cnt; // 計數子always @ (posedge i_clk, negedge i_rst_n)if (!i_rst_n)cnt <= 0;elsecnt <= cnt + 1'b1;wire seg7_clk = cnt[16]; // (2^17/50M = 2.6114)ms //-------------------------------------- // 分頻部分 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 動態掃描, 生成seg7_addr 開始 //++++++++++++++++++++++++++++++++++++++ reg [2:0] seg7_addr; // 第幾個seg7always @ (posedge seg7_clk, negedge i_rst_n)if (!i_rst_n)seg7_addr <= 0;elseseg7_addr <= seg7_addr + 1'b1; //-------------------------------------- // 動態掃描, 生成seg7_addr 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 根據seg7_addr, 譯出位碼 開始 //++++++++++++++++++++++++++++++++++++++ reg [2:0] o_sel_r; // 位選碼寄存器// 開發板上SEG7的方向是低位在左,高位在右 // 但是實際上我們看數的方向是高位在左,低位在右 // 故此處將第0位對應DIG[7],第7位對應DIG[0] alwayscase (seg7_addr)0 : o_sel_r = 3'b111; // SEG7[7]1 : o_sel_r = 3'b110; // SEG7[6]2 : o_sel_r = 3'b101; // SEG7[5]3 : o_sel_r = 3'b100; // SEG7[4] 4 : o_sel_r = 3'b011; // SEG7[3]5 : o_sel_r = 3'b010; // SEG7[2]6 : o_sel_r = 3'b001; // SEG7[1]7 : o_sel_r = 3'b000; // SEG7[0]endcase //-------------------------------------- // 根據seg7_addr, 譯出位碼 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 根據seg7_addr, 選擇熄滅碼 開始 //++++++++++++++++++++++++++++++++++++++ reg turn_off_r; // 熄滅碼alwayscase (seg7_addr)0 : turn_off_r = i_turn_off[0];1 : turn_off_r = i_turn_off[1];2 : turn_off_r = i_turn_off[2];3 : turn_off_r = i_turn_off[3];4 : turn_off_r = i_turn_off[4];5 : turn_off_r = i_turn_off[5];6 : turn_off_r = i_turn_off[6];7 : turn_off_r = i_turn_off[7];endcase //-------------------------------------- // 根據seg7_addr, 選擇熄滅碼 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 根據seg7_addr, 選擇小數點碼 開始 //++++++++++++++++++++++++++++++++++++++ reg dp_r; // 小數點碼alwayscase (seg7_addr)0 : dp_r = i_dp[0];1 : dp_r = i_dp[1];2 : dp_r = i_dp[2];3 : dp_r = i_dp[3];4 : dp_r = i_dp[4];5 : dp_r = i_dp[5];6 : dp_r = i_dp[6];7 : dp_r = i_dp[7];endcase //-------------------------------------- // 根據seg7_addr, 選擇小數點碼 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 根據seg7_addr, 選擇待譯段碼 開始 //++++++++++++++++++++++++++++++++++++++ reg [3:0] seg_data_r; // 待譯段碼alwayscase (seg7_addr)0 : seg_data_r = i_data[3:0];1 : seg_data_r = i_data[7:4];2 : seg_data_r = i_data[11:8];3 : seg_data_r = i_data[15:12];4 : seg_data_r = i_data[19:16];5 : seg_data_r = i_data[23:20];6 : seg_data_r = i_data[27:24];7 : seg_data_r = i_data[31:28];endcase //-------------------------------------- // 根據seg7_addr, 選擇待譯段碼 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 根據熄滅碼/小數點碼/待譯段碼 // 譯出段碼,開始 //++++++++++++++++++++++++++++++++++++++ reg [7:0] o_seg_r; // 段碼寄存器/** 0* -------* | |* 5| 6 |1 * -------* | |* 4| |2* ------- . 7* 3*/// 共陽 always @ (posedge i_clk, negedge i_rst_n)if (!i_rst_n)o_seg_r <= 8'hFF; // 送熄滅碼elseif(turn_off_r) // 送熄滅碼o_seg_r <= 8'hFF;elseif(!dp_r)case(seg_data_r) // 無小數點4'h0 : o_seg_r <= 8'hC0;4'h1 : o_seg_r <= 8'hF9;4'h2 : o_seg_r <= 8'hA4;4'h3 : o_seg_r <= 8'hB0;4'h4 : o_seg_r <= 8'h99;4'h5 : o_seg_r <= 8'h92;4'h6 : o_seg_r <= 8'h82;4'h7 : o_seg_r <= 8'hF8;4'h8 : o_seg_r <= 8'h80;4'h9 : o_seg_r <= 8'h90;4'hA : o_seg_r <= 8'h88;4'hB : o_seg_r <= 8'h83;4'hC : o_seg_r <= 8'hC6;4'hD : o_seg_r <= 8'hA1;4'hE : o_seg_r <= 8'h86;4'hF : o_seg_r <= 8'h8E;endcaseelsecase(seg_data_r) // 加小數點4'h0 : o_seg_r <= 8'hC0 ^ 8'h80;4'h1 : o_seg_r <= 8'hF9 ^ 8'h80;4'h2 : o_seg_r <= 8'hA4 ^ 8'h80;4'h3 : o_seg_r <= 8'hB0 ^ 8'h80;4'h4 : o_seg_r <= 8'h99 ^ 8'h80;4'h5 : o_seg_r <= 8'h92 ^ 8'h80;4'h6 : o_seg_r <= 8'h82 ^ 8'h80;4'h7 : o_seg_r <= 8'hF8 ^ 8'h80;4'h8 : o_seg_r <= 8'h80 ^ 8'h80;4'h9 : o_seg_r <= 8'h90 ^ 8'h80;4'hA : o_seg_r <= 8'h88 ^ 8'h80;4'hB : o_seg_r <= 8'h83 ^ 8'h80;4'hC : o_seg_r <= 8'hC6 ^ 8'h80;4'hD : o_seg_r <= 8'hA1 ^ 8'h80;4'hE : o_seg_r <= 8'h86 ^ 8'h80;4'hF : o_seg_r <= 8'h8E ^ 8'h80;endcase //-------------------------------------- // 根據熄滅碼/小數點碼/待譯段碼 // 譯出段碼,結束 //--------------------------------------assign o_sel = o_sel_r; // 寄存器輸出位選碼 assign o_seg = o_seg_r; // 寄存器輸出段碼endmodule版本2
頂層例化文件
module seg7x8(input CLOCK_50, // 板載50MHz時鐘 input [1:1] KEY, // KEY[1]output [7:0] SEG7_SEG, // 七段數碼管 段腳 output [7:0] SEG7_DIG // 七段數碼管 位腳 );// 顯示效果: // ------------------------- // |1 |2.|3 |4 | |B |C |D | // ------------------------- seg7x8_drive u0(.i_clk (CLOCK_50),.i_rst_n (KEY),.i_turn_off (8'b0000_1000), // 熄滅位[2進制][此處取第3位.i_dp (8'b0100_0000), // 小數點位[2進制][此處取第6位.i_data (32'h1234_ABCD), // 欲顯數據[16進制].o_seg (SEG7_SEG),.o_dig (SEG7_DIG) );endmodule驅動文件
module seg7x8_drive(input i_clk,input i_rst_n,input [7:0] i_turn_off, // 熄滅位[2進制input [7:0] i_dp, // 小數點位[2進制input [31:0] i_data, // 欲顯數據[16進制 output [7:0] o_seg, // 段腳output [7:0] o_dig // 位腳 );//++++++++++++++++++++++++++++++++++++++ // 分頻部分 開始 //++++++++++++++++++++++++++++++++++++++ reg [16:0] cnt; // 計數子always @ (posedge i_clk, negedge i_rst_n)if (!i_rst_n)cnt <= 0;elsecnt <= cnt + 1'b1;wire seg7_clk = cnt[16]; // (2^17/50M = 2.6114)ms //-------------------------------------- // 分頻部分 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 動態掃描, 生成seg7_addr 開始 //++++++++++++++++++++++++++++++++++++++ reg [2:0] seg7_addr; // 第幾個seg7always @ (posedge seg7_clk, negedge i_rst_n)if (!i_rst_n)seg7_addr <= 0;elseseg7_addr <= seg7_addr + 1'b1; //-------------------------------------- // 動態掃描, 生成seg7_addr 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 根據seg7_addr, 譯出位碼 開始 //++++++++++++++++++++++++++++++++++++++ reg [7:0] o_dig_r; // 位碼寄存器// 開發板上SEG7的方向是低位在左,高位在右 // 但是實際上我們看數的方向是高位在左,低位在右 // 故此處將第0位對應DIG[7],第7位對應DIG[0] alwayscase (seg7_addr)0 : o_dig_r = 8'b0000_0001;1 : o_dig_r = 8'b0000_0010;2 : o_dig_r = 8'b0000_0100;3 : o_dig_r = 8'b0000_1000;4 : o_dig_r = 8'b0001_0000;5 : o_dig_r = 8'b0010_0000;6 : o_dig_r = 8'b0100_0000;7 : o_dig_r = 8'b1000_0000;endcase //-------------------------------------- // 根據seg7_addr, 譯出位碼 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 根據seg7_addr, 選擇熄滅碼 開始 //++++++++++++++++++++++++++++++++++++++ reg turn_off_r; // 熄滅碼alwayscase (seg7_addr)0 : turn_off_r = i_turn_off[0];1 : turn_off_r = i_turn_off[1];2 : turn_off_r = i_turn_off[2];3 : turn_off_r = i_turn_off[3];4 : turn_off_r = i_turn_off[4];5 : turn_off_r = i_turn_off[5];6 : turn_off_r = i_turn_off[6];7 : turn_off_r = i_turn_off[7];endcase //-------------------------------------- // 根據seg7_addr, 選擇熄滅碼 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 根據seg7_addr, 選擇小數點碼 開始 //++++++++++++++++++++++++++++++++++++++ reg dp_r; // 小數點碼alwayscase (seg7_addr)0 : dp_r = i_dp[0];1 : dp_r = i_dp[1];2 : dp_r = i_dp[2];3 : dp_r = i_dp[3];4 : dp_r = i_dp[4];5 : dp_r = i_dp[5];6 : dp_r = i_dp[6];7 : dp_r = i_dp[7];endcase //-------------------------------------- // 根據seg7_addr, 選擇小數點碼 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 根據seg7_addr, 選擇待譯段碼 開始 //++++++++++++++++++++++++++++++++++++++ reg [3:0] seg_data_r; // 待譯段碼alwayscase (seg7_addr)0 : seg_data_r = i_data[3:0];1 : seg_data_r = i_data[7:4];2 : seg_data_r = i_data[11:8];3 : seg_data_r = i_data[15:12];4 : seg_data_r = i_data[19:16];5 : seg_data_r = i_data[23:20];6 : seg_data_r = i_data[27:24];7 : seg_data_r = i_data[31:28];endcase //-------------------------------------- // 根據seg7_addr, 選擇待譯段碼 結束 //--------------------------------------//++++++++++++++++++++++++++++++++++++++ // 根據熄滅碼/小數點碼/待譯段碼 // 譯出段碼,開始 //++++++++++++++++++++++++++++++++++++++ reg [7:0] o_seg_r; // 段碼寄存器/** 0* -------* | |* 5| 6 |1 * -------* | |* 4| |2* ------- . 7* 3*/// 共陽 always @ (posedge i_clk, negedge i_rst_n)if (!i_rst_n)o_seg_r <= 8'hFF; // 送熄滅碼elseif(turn_off_r) // 送熄滅碼o_seg_r <= 8'hFF;elseif(!dp_r)case(seg_data_r) // 無小數點4'h0 : o_seg_r <= 8'hC0;4'h1 : o_seg_r <= 8'hF9;4'h2 : o_seg_r <= 8'hA4;4'h3 : o_seg_r <= 8'hB0;4'h4 : o_seg_r <= 8'h99;4'h5 : o_seg_r <= 8'h92;4'h6 : o_seg_r <= 8'h82;4'h7 : o_seg_r <= 8'hF8;4'h8 : o_seg_r <= 8'h80;4'h9 : o_seg_r <= 8'h90;4'hA : o_seg_r <= 8'h88;4'hB : o_seg_r <= 8'h83;4'hC : o_seg_r <= 8'hC6;4'hD : o_seg_r <= 8'hA1;4'hE : o_seg_r <= 8'h86;4'hF : o_seg_r <= 8'h8E;endcaseelsecase(seg_data_r) // 加小數點4'h0 : o_seg_r <= 8'hC0 ^ 8'h80;4'h1 : o_seg_r <= 8'hF9 ^ 8'h80;4'h2 : o_seg_r <= 8'hA4 ^ 8'h80;4'h3 : o_seg_r <= 8'hB0 ^ 8'h80;4'h4 : o_seg_r <= 8'h99 ^ 8'h80;4'h5 : o_seg_r <= 8'h92 ^ 8'h80;4'h6 : o_seg_r <= 8'h82 ^ 8'h80;4'h7 : o_seg_r <= 8'hF8 ^ 8'h80;4'h8 : o_seg_r <= 8'h80 ^ 8'h80;4'h9 : o_seg_r <= 8'h90 ^ 8'h80;4'hA : o_seg_r <= 8'h88 ^ 8'h80;4'hB : o_seg_r <= 8'h83 ^ 8'h80;4'hC : o_seg_r <= 8'hC6 ^ 8'h80;4'hD : o_seg_r <= 8'hA1 ^ 8'h80;4'hE : o_seg_r <= 8'h86 ^ 8'h80;4'hF : o_seg_r <= 8'h8E ^ 8'h80;endcase //-------------------------------------- // 根據熄滅碼/小數點碼/待譯段碼 // 譯出段碼,結束 //--------------------------------------/* * | c[1] * b[in] -| * | e[out] */ assign o_dig = ~o_dig_r; // 寄存器輸出位碼 assign o_seg = o_seg_r; // 寄存器輸出段碼endmodule轉載于:https://www.cnblogs.com/yuphone/archive/2011/04/24/2026318.html
總結
以上是生活随笔為你收集整理的[原创].七段数码管驱动,Verilog版本的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 中小企业如何规避因员工跳槽而产生的风险?
- 下一篇: 易混淆的路由概念