各位大神好!
小弟刚接触FPGA不久,按照教程学到的知识半琢磨半参考写了一个8位二进制代码转化为3位BCD的代码,但烧到板上怎么也显示不对。代码我传到附件上,还请各位大神不吝赐教。
功能:通过拨片开关输入8位二进制数,在led 显示输入的数字。完成输入后按翻转开关K1 start ,使用大四加三算法转化为三位BCD,最后在7位数码管上显示转化后的BCD数值。
错误描述:上电后显示000,但按start后显示奇怪的数字。
贴源码如下:
`timescale 1ns /1ps
//输入一个8位二进制数,通过大四加三法转换为十进制的BCD码,在7段数码管进行显示输出
module Bit8_Bin_BCD(
clk,rst_n,
sw,
start,
led,
sm_sel,
sm_db
);
input clk; //50Mhz
input rst_n; //reset, 0--effect
input[7:0] sw; //8 bit switch
input start; //翻转开关1,待输入完数字后开启转换开关
output[3:0] sm_sel; //7-bit digit light select
output[6:0] sm_db; //7-bit digit light segment
output[7:0] led; //led reflect switch
reg[19:0] cnt; //20ms 1,000,000 clk
always @(posedge clk or negedge rst_n)
if (~rst_n) cnt <= 20'd0;
else if (cnt <= 20'hf4240) cnt <= cnt+1'b1;
else cnt <= 20'd0;
reg[7:0] sw_r; //switch
always @(posedge clk or negedge rst_n)
if (~rst_n) sw_r <= 8'd0;
else if (cnt == 20'hf4240) sw_r <= sw;
reg[7:0] led_r; //led
always @(posedge clk or negedge rst_n)
if (~rst_n) led_r <= 8'b11111111;
else led_r <= ~sw_r;
assign led = led_r;
//--------------------------------Get the num
reg[7:0] num;
always @(posedge clk or negedge rst_n)
if (~rst_n) num <= 8'd0;
else num <= sw_r;
//-------------------------------get start
reg low_sw;
always @(posedge clk or negedge rst_n)
if (~rst_n) low_sw <= 1'b1;
else if (cnt == 20'hf4240) low_sw <= start;
reg low_sw_r;
always @(posedge clk or negedge rst_n)
if (~rst_n) low_sw_r <= 1'b1;
else low_sw_r <= low_sw;
wire start_ctrl = low_sw_r & ~low_sw;
reg start_r;
always @(posedge clk or negedge rst_n)
if (~rst_n) start_r <= 1'b0;
else if(start_ctrl) start_r <= ~start_r;
//---------------------------------if start ,then launch BIN to BCD
parameter DATA_WIDTH = 8;
parameter SHIFT_DEPTH = 8;
localparam IDLE = 3'b001; //IDLE状态循环监测是否有start讯号,如果有则开始转换
localparam SHIFT = 3'b010; //转换状态
localparam DONE = 3'b100; //转换完成状态
reg[2:0] pre_state;
reg[2:0] next_state;
//
reg[SHIFT_DEPTH-1:0] shift_cnt;
//
reg[DATA_WIDTH-1:0] data_r;
//
reg[3:0] huns_r;
reg[3:0] tens_r;
reg[3:0] unit_r;
//
reg[3:0] huns_out;
reg[3:0] tens_out;
reg[3:0] unit_out;
//
reg trans_done;
//
wire[3:0] huns_data;
wire[3:0] tens_data;
wire[3:0] unit_data;
//
wire[3:0] huns_tmp;
wire[3:0] tens_tmp;
wire[3:0] unit_tmp;
//-------------------------
//step 1
always @(posedge clk or negedge rst_n)
if (~rst_n) pre_state <= IDLE;
else if (cnt == 20'hf4240) pre_state <= next_state;
//--------------------------
//step 2
always @(*)
begin
case(pre_state)
IDLE:
begin
if(start_r) next_state = SHIFT;
else next_state = IDLE;
end
SHIFT:
begin
if(shift_cnt == SHIFT_DEPTH + 1) next_state = DONE;
else next_state = SHIFT;
end
DONE:
begin
next_state = IDLE;
end
default: next_state = IDLE;
endcase
end
//---------------------------------
//step 3
always @(posedge clk or negedge rst_n)
if(~rst_n)
begin
huns_r <= 4'b0;
tens_r <= 4'b0;
unit_r <= 4'b0;
trans_done <= 1'b0;
shift_cnt <= 'd0;
data_r <= 'd0;
end
else
begin
case(next_state)
IDLE:
begin
huns_r <= 4'b0;
tens_r <= 4'b0;
unit_r <= 4'b0;
trans_done <= 1'b0;
shift_cnt <= 'd0;
data_r <= num;
end
SHIFT:
begin
if (shift_cnt == SHIFT_DEPTH + 1) shift_cnt <= 'd0;
else
begin
shift_cnt <= shift_cnt + 1'b1;
data_r <= data_r << 1;
unit_r <= {unit_tmp[2:0], data_r[DATA_WIDTH - 1]};
tens_r <= {tens_tmp[2:0], unit_tmp[3]};
huns_r <= {huns_tmp[2:0], tens_tmp[3]};
end
end
DONE:
begin
trans_done <= 1'b1;
end
default:
begin
huns_r <= huns_r;
tens_r <= tens_r;
unit_r <= unit_r;
trans_done <= trans_done;
shift_cnt <= shift_cnt;
end
endcase
end
//-------------------------------------
always @(posedge clk or negedge rst_n)
if (~rst_n)
begin
huns_out <= 4'b0;
tens_out <= 4'b0;
unit_out <= 4'b0;
end
else if (trans_done)
begin
huns_out <= huns_r;
tens_out <= tens_r;
unit_out <= unit_r;
end
else
begin
huns_out <= huns_out;
tens_out <= tens_out;
unit_out <= unit_out;
end
//-----------------------------------------
assign huns_tmp = (huns_r > 4'd4)? (huns_r + 2'd3): huns_r;
assign tens_tmp = (tens_r > 4'd4)? (tens_r + 2'd3): tens_r;
assign unit_tmp = (unit_r > 4'd4)? (unit_r + 2'd3): unit_r;
//
assign huns_data = huns_out;
assign tens_data = tens_out;
assign unit_data = unit_out;
//-------------------------------------- // 在7位数码管进行显示
//-------------------------------
/* 共阴极 :不带小数点
;0, 1, 2, 3, 4, 5, 6, 7,
db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h
;8, 9, a, b, c, d, e, f , 灭
db 7fh,6fh,77h,7ch,39h,5eh,79h,71h,00h*/
parameter seg0 = 7'h3f,
seg1 = 7'h06,
seg2 = 7'h5b,
seg3 = 7'h4f,
seg4 = 7'h66,
seg5 = 7'h6d,
seg6 = 7'h7d,
seg7 = 7'h07,
seg8 = 7'h7f,
seg9 = 7'h6f,
sega = 7'h77,
segb = 7'h7c,
segc = 7'h39,
segd = 7'h5e,
sege = 7'h79,
segf = 7'h71;
//-------------------------------------
reg[3:0] sm_sel_r;
reg[6:0] sm_dbr;
reg[7:0] cnt_sel;
always @(posedge clk or negedge rst_n)
if (~rst_n) cnt_sel <= 8'd0;
else if (cnt_sel <= 8'd150) cnt_sel <= cnt_sel + 1'b1;
else cnt_sel <= 8'd0;
always @(posedge clk or negedge rst_n)
if (~rst_n)
begin
sm_sel_r <= 4'b1111;
sm_dbr <= 7'd0;
end
else if (cnt_sel < 8'd50)
begin
sm_sel_r <= 4'b1101;
case(huns_data)
4'h0: sm_dbr <= seg0;
4'h1: sm_dbr <= seg1;
4'h2: sm_dbr <= seg2;
4'h3: sm_dbr <= seg3;
4'h4: sm_dbr <= seg4;
4'h5: sm_dbr <= seg5;
4'h6: sm_dbr <= seg6;
4'h7: sm_dbr <= seg7;
4'h8: sm_dbr <= seg8;
4'h9: sm_dbr <= seg9;
4'ha: sm_dbr <= sega;
4'hb: sm_dbr <= segb;
4'hc: sm_dbr <= segc;
4'hd: sm_dbr <= segd;
4'he: sm_dbr <= sege;
4'hf: sm_dbr <= segf;
default: ;
endcase
end
else if ((cnt_sel >= 8'd50) && (cnt_sel < 8'd100))
begin
sm_sel_r <= 4'b1011;
case(tens_data)
4'h0: sm_dbr <= seg0;
4'h1: sm_dbr <= seg1;
4'h2: sm_dbr <= seg2;
4'h3: sm_dbr <= seg3;
4'h4: sm_dbr <= seg4;
4'h5: sm_dbr <= seg5;
4'h6: sm_dbr <= seg6;
4'h7: sm_dbr <= seg7;
4'h8: sm_dbr <= seg8;
4'h9: sm_dbr <= seg9;
4'ha: sm_dbr <= sega;
4'hb: sm_dbr <= segb;
4'hc: sm_dbr <= segc;
4'hd: sm_dbr <= segd;
4'he: sm_dbr <= sege;
4'hf: sm_dbr <= segf;
default: ;
endcase
end
else
begin
sm_sel_r <= 4'b0111;
case(unit_data)
4'h0: sm_dbr <= seg0;
4'h1: sm_dbr <= seg1;
4'h2: sm_dbr <= seg2;
4'h3: sm_dbr <= seg3;
4'h4: sm_dbr <= seg4;
4'h5: sm_dbr <= seg5;
4'h6: sm_dbr <= seg6;
4'h7: sm_dbr <= seg7;
4'h8: sm_dbr <= seg8;
4'h9: sm_dbr <= seg9;
4'ha: sm_dbr <= sega;
4'hb: sm_dbr <= segb;
4'hc: sm_dbr <= segc;
4'hd: sm_dbr <= segd;
4'he: sm_dbr <= sege;
4'hf: sm_dbr <= segf;
default: ;
endcase
end
//-------------------------------------------
assign sm_sel = sm_sel_r;
assign sm_db = sm_dbr;
/*reg[7:0] led_r;
always @(posedge clk or negedge rst_n)
if (~rst_n) led_r <= 8'b11111111;
else begin
led_r[7:4] <= ~huns_r;
led_r[3:0] <= ~unit_r;
end
assign led = led_r;
*/
endmodule
|
|