1. 程式人生 > >AC620FPGA學習筆記——BCD數碼管

AC620FPGA學習筆記——BCD數碼管

AC620FPGA學習筆記——BCD數碼管

BCD數碼管

工程地址:https://github.com/HaHaHaHaHaGe/Planof2019_half/tree/master/Course_Project/FPGA/class03_hc595


實現8個8位數碼管,根據分頻後的時鐘自動計數(16進位制)

硬體結構

開發板:AC620
在這裡插入圖片描述

整體框架

在這裡插入圖片描述

BCDDisplay模組

在這裡插入圖片描述
根據輸入的data每4位為1組,共8組,對應8個數碼管,輪詢進行重新整理

device_74hc595模組

在這裡插入圖片描述
根據輸入的並行資料輸出序列資料,每次輸出後會產生鎖存脈衝(lock),在輸出過程中會產生busy高電平訊號,等傳輸完畢後恢復低電平。

程式碼部分

device_74hc595

module device_74hc595(
	clk,
	rst,
	data,
	busy,
	lock,
	lock595,
	out595,
clk595 ); input clk,rst,lock; input [15:0]data; output reg lock595,clk595,busy,out595; reg [4:0]send_cnt; reg [15:0]data_buffer; reg [1:0]flag; localparam SEND_STATE = 2'b00; localparam LOCK0_STATE = 2'b01; localparam LOCK1_STATE = 2'b11; localparam IDLE_STATE = 2'b10; [email protected](posedge clk,
negedge rst) if(!rst)begin send_cnt <= 5'b0; busy <= 1'b0; data_buffer <= 16'b0; flag <= IDLE_STATE; lock595 <= 1'b0; clk595 <= 1'b1; out595 <= 1'b0; end else case(flag) SEND_STATE: if(clk595) begin if(send_cnt == 5'd16) flag <= LOCK0_STATE; else begin send_cnt <= send_cnt + 5'b1; out595 <= data_buffer[5'd15-send_cnt]; clk595 <= 1'b0; end end else begin clk595 <= 1'b1; end LOCK0_STATE: begin lock595 <= 1'b1; flag <= LOCK1_STATE; end LOCK1_STATE: begin lock595 <= 1'b0; flag <= IDLE_STATE; end IDLE_STATE: if(lock)begin send_cnt <= 5'b0; data_buffer <= data; busy <= 1'b1; flag <= SEND_STATE; end else busy <= 1'b0; default: flag <= IDLE_STATE; endcase endmodule

BCDdecoder

module BCDdecoder(
	data,
	out
);
input [3:0]data;
output reg [7:0]out;
[email protected](*)
case(data)
 4'h0:out = 7'b1000000;             
 4'h1:out = 7'b1111001;             
 4'h2:out = 7'b0100100;             
 4'h3:out = 7'b0110000;             
 4'h4:out = 7'b0011001;             
 4'h5:out = 7'b0010010;             
 4'h6:out = 7'b0000010;             
 4'h7:out = 7'b1111000;             
 4'h8:out = 7'b0000000;             
 4'h9:out = 7'b0010000;             
 4'ha:out = 7'b0001000;             
 4'hb:out = 7'b0000011;             
 4'hc:out = 7'b1000110;             
 4'hd:out = 7'b0100001;             
 4'he:out = 7'b0000110;             
 4'hf:out = 7'b0001110; 
endcase
  
endmodule

frequencydivider

module frequencydivider(
	clk,
	rst,
	fclk
);

input clk,rst;
output reg fclk;

reg [31:0]cnt;

[email protected](posedge clk,negedge rst)
if(!rst) begin
	cnt <= 0;
	fclk <= 0;
end
else if(cnt == 500) begin
	cnt <= 0;
	fclk <= ~fclk;
end
else
	cnt <= cnt + 1;
	
endmodule

BCDDisplay

module BCDDisplay(
	clk,
	rst,
	data,
	lock595,
	out595,
	clk595
);
wire fclk;
input clk,rst;
input [31:0]data;
output lock595,out595,clk595;
reg flag;
reg [7:0]selecter;
reg [7:0]srcdata;
wire [7:0]dstdata;
reg [31:0]data_buffer;
reg lock;
wire busy;
reg doonce;
reg [7:0]cnt;

localparam Wait_Busy = 1'b0;
localparam Circle_Play = 1'b1;

BCDdecoder BCDdecoder_01(
	.data(srcdata),
	.out(dstdata)
);

frequencydivider frequencydivider_01(
	.clk(clk),
	.rst(rst),
	.fclk(fclk)
);

device_74hc595 device_74hc595_01(
	.clk(fclk),
	.rst(rst),
	.data({dstdata,selecter}),
	.busy(busy),
	.lock(lock),
	.lock595(lock595),
	.out595(out595),
	.clk595(clk595)
);
[email protected](posedge clk,negedge rst)
if(!rst) begin
	selecter <= 8'b0000_0001;
	data_buffer <= 32'b0;
	flag <= Circle_Play;
	srcdata <= 8'b0;
	lock <= 0;
	cnt <= 8'd4;
	doonce <= 0;
end
else begin
	data_buffer <= data;
	case(flag)
		Circle_Play: begin
			srcdata <= data_buffer >> cnt;
			selecter <= {selecter[6:0],selecter[7]};
			flag <= Wait_Busy;
			doonce <= 0;
			
			if(cnt == 8'd28)
				cnt <= 8'b0;
			else
				cnt <= cnt + 4;
		end
		Wait_Busy:
			if(busy) begin
				lock <= 0;
				doonce <= 1;
			end
			else if(doonce)
				flag <= Circle_Play;
			else
				lock <= 1;
	endcase
end
endmodule

頂層程式碼

module test_74hc595(
	clk,
	rst,
	key,
	lock595,
	out595,
	clk595
);
wire lock;
input clk;
input wire rst,key;
wire rst2;
reg [31:0]data;

output lock595,out595,clk595;

wire rst3;
wire clk2;

inkey inkey_1(
	.in(key),
	.out(lock),
	.clk(clk)
);

inkey inkey_2(
	.in(rst),
	.out(rst2),
	.clk(clk)
);


BCDDisplay BCDDisplay_1(
	.clk(clk),
	.rst(rst3),
	.data(data),
	.lock595(lock595),
	.out595(out595),
	.clk595(clk595)
);

frequencydivider frequencydivider2(
	.clk(clk),
	.rst(rst3),
	.fclk(clk2)
);


always @(negedge rst3,posedge clk2)
begin
if(!rst3)
	data <= 0;
else
	data <= data + 1;
end

assign rst3 = ~rst2;

endmodule