tear086 发表于 2009-11-14 10:36:40

七段数码管x8动态显示带熄灭和小数点控制(verilog)

新近写的,水平有限,欢迎拍砖。

原理图
http://cache.amobbs.com/bbs_upload782111/files_22/ourdev_503063.jpg
(原文件名:seg7 x 8.jpg)

源代码
--------------------------------------------------
/*
* seg7 x 8 查找表测试文件
*/

module seg7_test(
input         CLOCK_50,

output SEG7_DIG,
output SEG7_SEG
);

seg7_8_LUT u0(
.i_clock(CLOCK_50),
.i_turn_off(8'b1100_0000),// 熄灭位[此处取第7、6位
.i_dp(8'b0000_0100),      // 小数点位[此处取第2位
.i_data(32'hAB_CDEF),       // 欲显数据[16进制

.o_dig(SEG7_DIG),
.o_seg(SEG7_SEG)
);

endmodule
--------------------------------------------------

--------------------------------------------------
/*
* Name       : seg7_8_LUT
* Description: seg7 x 8 look up table; dynamic display;
*            with turn-off control and digit-point control
* Compiler   : Quartus II 9.0
* Author   : Yuphone Chang 张亚峰
* Aacademy   :Inner Mongolia University of Technology
* Blog       : http://blog.ednchina.com/2006tx_yafeng
* Version    : 1.0
* Change History:Revision 1.011.14, 2009
*                first edition
*/

module seg7_8_LUT(
    input         i_clock,    // 50MHz左右
    input      i_turn_off, // 熄灭位
    input      i_dp,       // 小数点位
    input   i_data,   // 欲显数据[16进制
   
    output wire           o_dig,// 位脚
    output wire           o_seg   // 段脚
);

reg o_dig_r;      // 位选码缓存器
reg o_seg_r;      // 段码缓存器

reg seg7_addr_r;// 第?个seg7

reg       turn_off_r;   // 熄灭flag
reg       dp_r;         // 小数点flag
reg seg_data_r;   // 待译段码
                       
reg                delay_cnt;// 延时计数子


// 动态扫描, 每2.5ms换一个seg7
always@ (posedge i_clock)
begin
    delay_cnt <= delay_cnt + 17'b1;
        if(delay_cnt >= 125_000)   // 125000/50M = 2.5ms
        begin
       seg7_addr_r<=seg7_addr_r + 3'b1;
      delay_cnt   <= 17'b0;
        end               
end

// 根据seg7_addr_r, 译出位码
always@ (posedge i_clock)
begin
    case(seg7_addr_r)
      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
end


// 根据seg7_addr_r, 选择熄灭flag/小数点flag/待译段码
always@ (posedge i_clock)
begin
    case(seg7_addr_r)
      0 : begin
            turn_off_r= i_turn_off;
            dp_r      = i_dp;
            seg_data_r= i_data;
            end
      1 : begin
            turn_off_r= i_turn_off;
            dp_r      = i_dp;
            seg_data_r= i_data;
            end
      2 : begin
            turn_off_r= i_turn_off;
            dp_r      = i_dp;
            seg_data_r= i_data;
            end
      3 : begin
            turn_off_r= i_turn_off;
            dp_r      = i_dp;
            seg_data_r= i_data;
            end
      4 : begin
            turn_off_r= i_turn_off;
            dp_r      = i_dp;
            seg_data_r= i_data;
            end
      5 : begin
            turn_off_r= i_turn_off;
            dp_r      = i_dp;
            seg_data_r= i_data;
            end
      6 : begin
            turn_off_r= i_turn_off;
            dp_r      = i_dp;
            seg_data_r= i_data;
            end
      7 : begin
            turn_off_r= i_turn_off;
            dp_r      = i_dp;
            seg_data_r= i_data;
            end
    endcase
end

/*
*   0
*-------
*|   |
* 5|6|1
*-------
*|   |
* 4|   |2
*-------   . 7
*    3
*/
// 根据熄灭flag/小数点flag/待译段码, 译出段码
always@ *
begin
if(turn_off_r)      // 送熄灭码
      o_seg_r = 8'hFF;
else
begin
    if(dp_r)
    begin
      case(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
    end
    else
    begin
      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;
      endcase
    end
end
end

/*
*      | c
* b -|
*      | e
*/
assign o_dig = ~o_dig_r; // 共阳,但经过三极管反向
assign o_seg = o_seg_r;

endmodule
--------------------------------------------------

xukaiming 发表于 2009-11-15 01:07:30

mark

sunjie718 发表于 2010-5-14 23:38:18

页: [1]
查看完整版本: 七段数码管x8动态显示带熄灭和小数点控制(verilog)