PGA开发板DIY—sdjntl的进程贴
1、 LED闪烁灯、LED流水灯、LED跑马灯
2、 PLL 控制LED
4、 按键防抖动控制LED灯
5、 拔码开关控制LED灯
6、 数码管静态显示
7、 数码管动态显示
8、 数码管数字时钟
9、 LCD1602的显示
10、 LCD24064的显示
11、 串口收发数据
12、 读取PS2接口
1、 LED闪烁灯、LED流水灯、LED跑马灯
1、实验内容
红灯常亮,绿灯常闪烁、黄灯工作模式指示。
按一定时间转换各种灯亮模式,
2、实验代码
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:
// Design Name:
// Module Name:
// Project Name:
// Target Device:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
`define DEBUG //调试
`ifdef DEBUG
`define LED_G 26'd16
`define LED_M 26'd16
`else
`define LED_G 26'd50_000_000
`define LED_M 26'd5_000_000
`endif
module led(
CLK_50MHZ,
RESET_N,
YELLOW,
RED,
GREEN,
LED
);
input CLK_50MHZ; //主时钟信号,50MHz
input RESET_N; //复位信号,低有效
output YELLOW,RED,GREEN;
output [7:0] LED;
assign RED = 1'b0;
reg led_g_clp;
reg [25:0] led_g_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N) begin
led_g_clp <= 1'b0;
led_g_cnt <= 26'd0;
end
else if(led_g_cnt == `LED_G) begin
led_g_clp <= ~led_g_clp;
led_g_cnt <= 26'd0;
end
else led_g_cnt <= led_g_cnt + 1'b1;
end
assign GREEN = led_g_clp;//工作灯
reg [25:0] led_move;//26'd5_000_000
reg led_clk;
reg [25:0] led_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N) begin
led_cnt <= 26'd0;
led_clk <= 1'b0;
end
else if(led_cnt == led_move) begin//`LED_M
led_cnt <= 26'd0;
led_clk <= ~led_clk;
end
else led_cnt <= led_cnt + 1'b1;
end
assign YELLOW = led_clk; //黄灯工作模式指示。
reg [7:0] led_r;
reg [3:0] state;
reg [2:0] led_m_cnt;
reg [2:0] led_m_cnt_r;
always @ (posedge led_clk or negedge RESET_N) begin
if(!RESET_N) begin
led_r <= 8'd0;
state <= 4'd0;
led_move <=`LED_M;// 26'd50_000_000;
end
else begin
case(state)
4'b0000:
begin
led_r <= 8'hff; //模式1全灭
state <= state + 1'b1;
end
4'b0001:
begin
led_r <= 8'h00;//模式2全亮
state <= state + 1'b1;
end
4'b0010:
begin
led_r <= 8'haa; //模式3隔位亮
state <= state + 1'b1;
end
4'b0011:
begin
led_r <= 8'h55; //模式4隔位灭
state <= state + 1'b1;
end
4'b0100:
begin
led_r <= 8'hf0; //模式5前半灭
state <= state + 1'b1;
end
4'b0101:
begin
led_r <= 8'h0f; //模式6前半亮
state <= state + 1'b1;
end
4'b0110:
begin
led_r <= 8'h24; //模式7隔多位亮
state <= state + 1'b1;
end
4'b0111:
begin
led_r <= 8'hdb; //模式8隔多位灭
led_m_cnt <= 3'h1;
led_m_cnt_r <= 3'h1;
led_move <= {led_move[2:0],led_move[25:3]};
//调节模式转换时间
state <= state + 1'b1;
end
4'b1000: //模式9渐多并移动
begin
/* if(led_m_cnt_r>0)begin
led_r <= {led_r[6:0],1'b1};
led_m_cnt_r <= led_m_cnt_r - 1'b1;
end
else
state <= 4'b0101;*/
case(led_m_cnt)
3'h1: led_r <= 8'b 0000_0001;
3'h2: led_r <= 8'b 0000_0011;
3'h3: led_r <= 8'b 0000_0111;
3'h4: led_r <= 8'b 0000_1111;
3'h5: led_r <= 8'b 0001_1111;
3'h6: led_r <= 8'b 0011_1111;
3'h7: led_r <= 8'b 0111_1111;
default: led_r <=8'b 0000_0000;
endcase
state <= state + 1'b1;
end
4'b1001:// 模式10一位亮向右移
begin
if(!led_r[7])begin
led_r <= {led_r[6:0],led_r[7]};
end
else if(led_m_cnt == 3'h7) begin
led_r <= 8'h80;
led_m_cnt <= 3'h0;
state <= 4'b1010;
end
else begin
led_m_cnt <= led_m_cnt + 1'b1;
led_m_cnt_r <= led_m_cnt;
state <= 4'b1000;
end
end
4'b1010: //模式11一位亮向左移
begin
if(led_m_cnt < 3'h7)begin
led_r <= {led_r[0],led_r[7:1]};
led_m_cnt <= led_m_cnt + 1'b1;
end
else
begin
led_r <= 8'h01;
led_m_cnt <= 3'h0;
state <= state + 1'b1;
end
end
4'b1011: //模式12一位灭向右移
begin
if(led_m_cnt < 3'h7)begin
led_r <= {led_r[6:0],led_r[7]};
led_m_cnt <= led_m_cnt + 1'b1;
end
else
begin
led_r <= 8'hfe;
led_m_cnt <= 3'h0;
state <= state + 1'b1;
end
end
4'b1100: //模式13一位灭向左移
begin
if(led_m_cnt < 3'h7)begin
led_r <= {led_r[6:0],led_r[7]};
led_m_cnt <= led_m_cnt + 1'b1;
end
else
begin
led_r <= 8'h7f;
led_m_cnt <= 3'h0;
state <= state + 1'b1;
end
end
4'b1101:
begin
if(led_m_cnt < 3'h7)begin
led_r <= {led_r[0],led_r[7:1]};
led_m_cnt <= led_m_cnt + 1'b1;
end
else
begin
led_move <= `LED_M;// 26'd50_000_000;
state <= 4'b0000; //返回
end
end
default: ;
endcase
end
end
assign LED = led_r;
endmodule
3、仿真文件
// Copyright (C) 1991-2008 Altera Corporation
// Your use of Altera Corporation's design tools, logic functions
// and other software and tools, and its AMPP partner logic
// functions, and any output files from any of the foregoing
// (including device programming or simulation files), and any
// associated documentation or information are expressly subject
// to the terms and conditions of the Altera Program License
// Subscription Agreement, Altera MegaCore Function License
// Agreement, or other applicable license agreement, including,
// without limitation, that your use is for the sole purpose of
// programming logic devices manufactured by Altera and sold by
// Altera or its authorized distributors. Please refer to the
// applicable agreement for further details.
// *****************************************************************************
// This file contains a Verilog test bench template that is freely editable to
// suit user's needs .Comments are provided in each section to help the user
// fill out necessary details.
// *****************************************************************************
// Generated on "11/29/2012 21:00:41"
// Verilog Test Bench template for design : led
//
// Simulation tool : ModelSim-Altera (Verilog)
//
`timescale 1 ps/ 1 ps
module led_vlg_tst();
// constants
// general purpose registers
//reg eachvec;
// test vector input registers
reg CLK_50MHZ;
reg RESET_N;
// wires
wire GREEN;
wire [7:0] LED;
wire RED;
wire YELLOW;
// assign statements (if any)
led i1 (
// port map - connection between master ports and signals/registers
.CLK_50MHZ(CLK_50MHZ),
.GREEN(GREEN),
.LED(LED),
.RED(RED),
.RESET_N(RESET_N),
.YELLOW(YELLOW)
);
initial
begin
CLK_50MHZ = 0;
RESET_N = 0;
#20
RESET_N = 1;
end
initial
begin
forever
#20
CLK_50MHZ = ~CLK_50MHZ;
end
endmodule
4、测试下载文件
led.rar
5、视频文件
PLL 控制LED
1、实验内容
50MHZ倍频到100MHZ,200MHZ,控制LED
2、实验代码
`define DEBUG
`ifdef DEBUG
`define CLK 26'd64
`define LED0 cnt_clk[5]
`define CLK_100M 27'd128
`define LED1 cnt_100m[6]
`define CLK_200M 27'd256
`define LED2 cnt_200m[7]
`else
`define CLK 26'd50_000_000
`define LED0 cnt_clk[25]
`define CLK_100M 27'd100_000_000
`define LED1 cnt_100m[26]
`define CLK_200M 28'd200_000_000
`define LED2 cnt_200m[27]
`endif
module pll_prj(
clk,
rst_n,
led0,led1,led2
);
output led0,led1,led2;
input clk;//50MHZ
input rst_n;//RESET
wire clk_c0;//100MHZ
wire clk_c1;//200MHZ
wire locked;
pll_ctr pll_ctr_inst (
.areset ( !rst_n ),
.inclk0 ( clk ),
.c0 ( clk_c0 ),
.c1 ( clk_c1 ),
.locked ( locked )
);
reg[25:0] cnt_clk;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) cnt_clk <= 26'd0;
else if(cnt_clk == `CLK) cnt_clk <= 26'd0;
else if(locked) cnt_clk <= cnt_clk + 1'b1;
end
assign led0 = `LED0;
reg[26:0] cnt_100m;
always@(posedge clk_c0 or negedge rst_n)
begin
if(!rst_n) cnt_100m <= 27'd0;
else if(cnt_100m == `CLK_100M) cnt_100m <= 27'd0;
else cnt_100m <= cnt_100m + 1'b1;
end
assign led1 = `LED1;
reg[27:0] cnt_200m;
always@(posedge clk_c1 or negedge rst_n)
begin
if(!rst_n) cnt_200m <= 28'd0;
else if(cnt_200m == `CLK_200M) cnt_200m <= 28'd0;
else cnt_200m <= cnt_200m + 1'b1;
end
assign led2 = `LED2;
endmodule
3、测试仿真
`timescale 1 ns/ 1 ns
module pll_prj_vlg_tst();
// constants
// general purpose registers
//reg eachvec;
// test vector input registers
reg clk;
reg rst_n;
// wires
wire led0;
wire led1;
wire led2;
// assign statements (if any)
pll_prj i1 (
// port map - connection between master ports and signals/registers
.clk(clk),
.led0(led0),
.led1(led1),
.led2(led2),
.rst_n(rst_n)
);
initial
begin
clk = 1;
rst_n = 0;
#20
rst_n = 1;
#5000
$stop;
end
initial
begin
forever
#20 clk = ~clk;
end
endmodule
4、测试下载文件
1、实验内容
读取按键并控制LED
2、实验代码
`define DEBUG
`ifdef DEBUG
`define S 27'd32
`define L led_cnt[4]
`else
`define S 27'd50_000_000
`define L led_cnt[25]
`endif
module key(
CLK_50MHZ,
RESET_N,
KEY,
RED,
LED
);
input CLK_50MHZ;
input RESET_N;
input [7:0] KEY;
output reg [7:0] LED;
output RED;
reg [26:0] led_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N)
led_cnt <= 27'd0;
else if(led_cnt >= `S)
led_cnt <= 27'd0;
else
led_cnt <= led_cnt + 1'b1;
end
assign RED = `L;
always @ (posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N)
LED <= 8'b0000_0000;
else
LED <= KEY;
end
endmodule
3、测试仿真
`timescale 1 ns/ 1 ns
module key_vlg_tst();
// constants
// general purpose registers
//reg eachvec;
// test vector input registers
reg CLK_50MHZ;
reg [7:0] KEY;
reg RESET_N;
// wires
wire [7:0] LED;
wire RED;
// assign statements (if any)
key i1 (
// port map - connection between master ports and signals/registers
.CLK_50MHZ(CLK_50MHZ),
.KEY(KEY),
.LED(LED),
.RESET_N(RESET_N),
.RED(RED)
);
initial
begin
CLK_50MHZ = 0;
RESET_N = 0;
#20
RESET_N = 1;
#100
KEY = 8'B0000_1111;
#100
KEY = 8'B1010_1010;
#1000
$stop;
end
initial
begin
forever
#20 CLK_50MHZ = ~CLK_50MHZ;
end
endmodule
4、测试下载文件
key.rar
4、按键防抖动控制LED灯
1、 实验内容
按键防抖动控制
2、 实验代码
//`define DEBUG
`ifdef DEBUG
`define MS 20'h0000f
`else
`define MS 20'hffff0
`endif
module keysw(
CLK_50MHZ,
RESET_N,
KEY,
LED
);
input CLK_50MHZ;
input RESET_N;
input [7:0] KEY;
output [7:0] LED;
reg[7:0] key_rst;
always @( posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N) key_rst<= 8'b1111_1111;
else key_rst<= KEY;
end
reg[7:0] key_rst_r;
always @( posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N) key_rst_r <= 8'b1111_1111;
else key_rst_r <=key_rst;
end
wire[7:0] key_d;//维持一个时钟周期
assign key_d = key_rst & (~key_rst_r);
reg[19:0]key_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N)
key_cnt <= 20'd0;
else if((key_cnt == `MS + 1'B1)|key_d)
key_cnt <= 20'd0;
else
key_cnt <= key_cnt +1'b1;
end
reg[7:0] sw;
always @( posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N) sw <= 8'b1111_1111;
else if(key_cnt == `MS) sw <= KEY;
end
reg[7:0] sw_r;
always @( posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N) sw_r <= 8'b1111_1111;
else sw_r <= sw;
end
wire[7:0] key_ctrl;//维持一个时钟周期
assign key_ctrl = sw & (~sw_r);
reg[7:0] key_en;
always @ (posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N) key_en <= 8'b0000_0000;
else
begin
if(key_ctrl[0]) key_en[0] <= ~key_en[0];
if(key_ctrl[1]) key_en[1] <= ~key_en[1];
if(key_ctrl[2]) key_en[2] <= ~key_en[2];
if(key_ctrl[3]) key_en[3] <= ~key_en[3];
if(key_ctrl[4]) key_en[4] <= ~key_en[4];
if(key_ctrl[5]) key_en[5] <= ~key_en[5];
if(key_ctrl[6]) key_en[6] <= ~key_en[6];
if(key_ctrl[7]) key_en[7] <= ~key_en[7];
end
end
assign LED = key_en;
endmodule
3、 测试仿真
`timescale 1 ns/ 1 ns
module keysw_vlg_tst();
// constants
// general purpose registers
//reg eachvec;
// test vector input registers
reg CLK_50MHZ;
reg [7:0] KEY;
reg RESET_N;
// wires
wire [7:0] LED;
// assign statements (if any)
keysw i1 (
// port map - connection between master ports and signals/registers
.CLK_50MHZ(CLK_50MHZ),
.KEY(KEY),
.LED(LED),
.RESET_N(RESET_N)
);
initial
begin
CLK_50MHZ = 0;
RESET_N = 0;
#20
RESET_N = 1;
#20
KEY = 8'B000_1111;
#200
KEY = 8'B1111_0000;
#1000
KEY = 8'B1010_0101;
#20000
$stop;
end
initial
begin
forever
#20 CLK_50MHZ = ~CLK_50MHZ;
end
endmodule
4、 测试下载文件
key.rar
5、 拔码开关控制LED灯
1、 实验内容
拔码开关控制LED灯
2、 实验代码
//`define DEBUG
`ifdef DEBUG
`define LEDN led_cnt[5]
`else
`define LEDN led_cnt[25]
`endif
module sw(
RESET_N,
CLK_50MHZ,
SW,
LED,
RED,
BLUE,
GREEN
);
input RESET_N;
input CLK_50MHZ;
input [7:0] SW;
output [7:0] LED;
reg [7:0] LED;
output RED;
output BLUE;
output GREEN;
reg [25:0] led_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
led_cnt <= 26'd0;
else
led_cnt <= led_cnt + 1'b1;
end
assign BLUE = `LEDN;//led_cnt[25];
assign GREEN = ~BLUE;
assign RED = 1'b0;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
LED <= 8'b0101_1010;
else
LED <= SW;
end
endmodule
3、 测试仿真
`timescale 1 ns/ 1 ps
module sw_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg CLK_50MHZ;
reg RESET_N;
reg [7:0] SW;
// wires
wire [7:0] LED;
// assign statements (if any)
sw i1 (
// port map - connection between master ports and signals/registers
.CLK_50MHZ(CLK_50MHZ),
.LED(LED),
.RESET_N(RESET_N),
.SW(SW)
);
initial
begin
RESET_N = 0;
CLK_50MHZ = 0;
#20
RESET_N = 1;
SW = 8'B1111_0101;
#60
SW = 8'B0101_1010;
#100
SW = 8'B0111_1010;
#1000
$stop;
end
initial
begin
forever
#20 CLK_50MHZ = ~CLK_50MHZ;
end
endmodule
4、 测试下载文件
sw.rar
6、 数码管静态显示
1、 实验内容
数码管静态显示
2、 实验代码
`define DEBUG
`ifdef DEBUG
`define LEDN 26'd18
`define DIGN 26'd8
`else
`define LEDN 26'd5_000_000
`define DIGN 26'd50_000_000
`endif
module smg(
RESET_N,
CLK_50MHZ,
DIG,
SEG,
LED,
RED,
BLUE,
GREEN
);
input RESET_N;
input CLK_50MHZ;
output [7:0] LED;
output [7:0] DIG;
output [7:0] SEG;
output RED;
output BLUE;
output GREEN;
reg [25:0] led_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
led_cnt <= 26'd0;
else if(led_cnt == `LEDN)
led_cnt <= 26'd0;
else
led_cnt <= led_cnt + 1'b1;
end
assign BLUE = `LEDN;//led_cnt[25];
assign GREEN = ~BLUE;
assign RED = 1'b0;
assign DIG = 8'b0000_0000;
reg [3:0] dig_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
dig_cnt <= 4'd0;
else if(led_cnt==`DIGN)
dig_cnt <= dig_cnt + 1'b1;
end
reg [7:0] seg_r;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
case(dig_cnt)
4'h0 : seg_r = 8'hc0; // "0"
4'h1 : seg_r = 8'hf9; // "1"
4'h2 : seg_r = 8'ha4; // "2"
4'h3 : seg_r = 8'hb0; // "3"
4'h4 : seg_r = 8'h99; // "4"
4'h5 : seg_r = 8'h92; // "5"
4'h6 : seg_r = 8'h82; // "6"
4'h7 : seg_r = 8'hf8; // "7"
4'h8 : seg_r = 8'h80; // "8"
4'h9 : seg_r = 8'h90; // "9"
4'ha : seg_r = 8'h88; // "a"
4'hb : seg_r = 8'h83; // "b"
4'hc : seg_r = 8'hc6; // "c"
4'hd : seg_r = 8'ha1; // "d"
4'he : seg_r = 8'h86; // "e"
4'hf : seg_r = 8'h8e; // "f"
default: ;
endcase
end
assign SEG = seg_r;
assign LED = seg_r;
endmodule
3、 测试仿真
`timescale 1 ps/ 1 ps
module smg_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg CLK_50MHZ;
reg RESET_N;
// wires
wire BLUE;
wire [7:0] DIG;
wire GREEN;
wire [7:0] LED;
wire RED;
wire [7:0] SEG;
// assign statements (if any)
smg i1 (
// port map - connection between master ports and signals/registers
.BLUE(BLUE),
.CLK_50MHZ(CLK_50MHZ),
.DIG(DIG),
.GREEN(GREEN),
.LED(LED),
.RED(RED),
.RESET_N(RESET_N),
.SEG(SEG)
);
initial
begin
CLK_50MHZ = 0;
RESET_N = 0;
#20
RESET_N = 1;
end
initial
begin
forever
#20
CLK_50MHZ = ~CLK_50MHZ;
end
endmodule
4、 测试下载文件
smg.rar
7、 数码管动态显示
1、 实验内容
数码管动态显示
2、 实验代码
//`define DEBUG
`ifdef DEBUG
`define LEDN led_cnt[5]
`define DIGN 26'd8
`else
`define LEDN led_cnt[25]
`define DIGN 26'd50_000
`endif
module smg(
RESET_N,
CLK_50MHZ,
DIG,
SEG,
LED,
RED,
BLUE,
GREEN
);
input RESET_N;
input CLK_50MHZ;
output [7:0] LED;
output [7:0] DIG;
output [7:0] SEG;
output RED;
output BLUE;
output GREEN;
reg [25:0] led_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
led_cnt <= 26'd0;
else
led_cnt <= led_cnt + 1'b1;
end
assign BLUE = `LEDN;//led_cnt[25];
assign GREEN = ~BLUE;
assign RED = 1'b0;
reg [25:0] dis_cnt;
reg [2:0] dig_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N) begin
dis_cnt <= 26'd0;
dig_cnt <= 3'd0;
end
else if(dis_cnt==`DIGN) begin
dig_cnt <= dig_cnt + 1'b1;
dis_cnt <= 26'd0;
end
else
dis_cnt <= dis_cnt + 1'b1;
end
reg [7:0] seg_r;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
seg_r <= 8'd0;
else
begin
case(dig_cnt)
4'h0 : seg_r <= 8'hc0; // "0"
4'h1 : seg_r <= 8'hf9; // "1"
4'h2 : seg_r <= 8'ha4; // "2"
4'h3 : seg_r <= 8'hb0; // "3"
4'h4 : seg_r <= 8'h99; // "4"
4'h5 : seg_r <= 8'h92; // "5"
4'h6 : seg_r <= 8'h82; // "6"
4'h7 : seg_r <= 8'hf8; // "7"
/*4'h8 : seg_r <= 8'h80; // "8"
4'h9 : seg_r <= 8'h90; // "9"
4'ha : seg_r <= 8'h88; // "a"
4'hb : seg_r <= 8'h83; // "b"
4'hc : seg_r <= 8'hc6; // "c"
4'hd : seg_r <= 8'ha1; // "d"
4'he : seg_r <= 8'h86; // "e"
4'hf : seg_r <= 8'h8e; // "f"*/
default: ;
endcase
end
end
assign SEG = seg_r;
assign LED = seg_r;
reg [7:0] dig_r;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
dig_r <= 8'hfe;
else
begin
if(dis_cnt==`DIGN) dig_r <= {dig_r[6:0],dig_r[7] };
/*case(dig_cnt)
4'h0 : dig_r<= 8'hfe;
4'h1 : dig_r<= 8'hfd;
4'h2 : dig_r<= 8'hfb;
4'h3 : dig_r<= 8'hf7;
4'h4 : dig_r<= 8'hef;
4'h5 : dig_r<= 8'hdf;
4'h6 : dig_r<= 8'hbf;
4'h7 : dig_r<= 8'h7f;
default: ;
endcase*/
end
end
assign DIG = dig_r;
endmodule
3、 测试仿真
`timescale 1 ns/ 1 ns
module smgd_vlg_tst();
// constants
// general purpose registers
//reg eachvec;
// test vector input registers
reg CLK_50MHZ;
reg RESET_N;
// wires
wire [7:0] DIG;
wire [7:0] SEG;
// assign statements (if any)
smgd i1 (
// port map - connection between master ports and signals/registers
.CLK_50MHZ(CLK_50MHZ),
.DIG(DIG),
.RESET_N(RESET_N),
.SEG(SEG)
);
initial
begin
CLK_50MHZ = 0;
RESET_N = 0;
#20
RESET_N = 1;
#20000
$stop;
end
initial
begin
forever
#20 CLK_50MHZ = ~CLK_50MHZ;
end
endmodule
4、 测试下载文件
smg.rar
8、 数码管数字时钟
1、 实验内容
数码管数字时钟
2、 实验代码
timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date:
// Design Name:
// Module Name:
// Project Name:
// Target Device:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
`define DEBUG
`ifdef DEBUG
`define LEDN led_cnt[5]
`define DIGN 26'd8
`define CLKN 26'd8
`else
`define LEDN led_cnt[25]
`define DIGN 26'd50_000
`define CLKN 26'd50_000_0000
`endif
module smg(
RESET_N,
CLK_50MHZ,
DIG,
SEG,
LED,
RED,
BLUE,
GREEN
);
input RESET_N;
input CLK_50MHZ;
output [7:0] LED;
output [7:0] DIG;
output [7:0] SEG;
output RED;
output BLUE;
output GREEN;
reg [7:0] display[9:0];
initial begin
display[0] = 8'hC0;
display[1] = 8'hF9;
display[2] = 8'hA4;
display[3] = 8'hB0;
display[4] = 8'h99;
display[5] = 8'h92;
display[6] = 8'h82;
display[7] = 8'hF8;
display[8] = 8'h80;
display[9] = 8'h90;
end
reg [25:0] led_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
led_cnt <= 26'd0;
else
led_cnt <= led_cnt + 1'b1;
end
assign BLUE = `LEDN;//led_cnt[25];
assign GREEN = ~BLUE;
assign RED = 1'b0;
reg c_t;
reg [25:0] clk_cnt;
reg [3:0] ds_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N) begin
clk_cnt <= 26'd0;
ds_cnt <= 4'd0;
c_t <= 1'b0;
end
else if(clk_cnt==`CLKN) begin
clk_cnt <= 26'd0;
c_t <= ~c_t;
ds_cnt <= ds_cnt + 1'b1;
end
else
clk_cnt <= clk_cnt + 1'b1;
end
wire c_en;
assign c_en = (clk_cnt==`CLKN);
reg [5:0] s_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
s_cnt <= 6'd0;
else if(s_cnt == 6'd60)
s_cnt <= 6'd0;
else if(c_en)
s_cnt <= s_cnt + 1'b1;
end
wire s_en;
assign s_en = (s_cnt == 6'd60);
reg [5:0] m_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
m_cnt <= 6'd0;
else if(m_cnt == 6'd60)
m_cnt <= 6'd0;
else if(s_en)
m_cnt <= m_cnt + 1'b1;
end
wire m_en;
assign m_en = (m_cnt == 6'd60);
reg [4:0] t_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
t_cnt <= 5'd0;
else if(t_cnt == 5'd24)
t_cnt <= 5'd0;
else if(m_en)
t_cnt <= t_cnt + 1'b1;
end
reg [25:0] scan_cnt;
reg [2:0] scan_en;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N) begin
scan_cnt <= 26'd0;
scan_en <= 3'd0;
end
else if(scan_cnt==`DIGN) begin
scan_en <= scan_en + 1'b1;
scan_cnt <= 26'd0;
end
else
scan_cnt <= scan_cnt + 1'b1;
end
reg [7:0] seg_r;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
seg_r <= 8'd0;
else
begin
case(scan_en)
4'h0 : seg_r <= display[s_cnt%10];
4'h1 : seg_r <= display[s_cnt/10];
4'h2 : seg_r <= c_t ? 8'hbf:8'hff;
4'h3 : seg_r <= display[m_cnt%10];
4'h4 : seg_r <= display[m_cnt/10];
4'h5 : seg_r <= c_t ? 8'hff:8'hbf;
4'h6 : seg_r <= display[t_cnt%10];
4'h7 : seg_r <= display[t_cnt/10];
default: ;
endcase
end
end
assign SEG = seg_r;
assign LED = display[s_cnt%10];
reg [7:0] dig_r;
always @ (posedge CLK_50MHZ or negedge RESET_N) begin
if(!RESET_N)
dig_r <= 8'hfe;
else
begin
if(scan_cnt==`DIGN) dig_r <= {dig_r[6:0],dig_r[7] };//(scan_en)
/*case(dig_cnt)
4'h0 : dig_r<= 8'hfe;
4'h1 : dig_r<= 8'hfd;
4'h2 : dig_r<= 8'hfb;
4'h3 : dig_r<= 8'hf7;
4'h4 : dig_r<= 8'hef;
4'h5 : dig_r<= 8'hdf;
4'h6 : dig_r<= 8'hbf;
4'h7 : dig_r<= 8'h7f;
default: ;
endcase*/
end
end
assign DIG = dig_r;
endmodule
3、 测试仿真
`timescale 1 ps/ 1 ps
module smg_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg CLK_50MHZ;
reg RESET_N;
// wires
wire BLUE;
wire [7:0] DIG;
wire GREEN;
wire [7:0] LED;
wire RED;
wire [7:0] SEG;
// assign statements (if any)
smg i1 (
// port map - connection between master ports and signals/registers
.BLUE(BLUE),
.CLK_50MHZ(CLK_50MHZ),
.DIG(DIG),
.GREEN(GREEN),
.LED(LED),
.RED(RED),
.RESET_N(RESET_N),
.SEG(SEG)
);
initial
begin
CLK_50MHZ = 0;
RESET_N = 0;
#30
RESET_N =1;
end
initial
begin
forever
#20
CLK_50MHZ = ~CLK_50MHZ;
end
endmodule
4、 测试下载文件
smg.rar
9、 LCD1602的显示
1、 实验内容
LCD1602的显示
2、 实验代码
`define DEBUG
`ifdef DEBUG
`define LEDA led_cnt[5]
`define LEDB led_cnt[4]
`define CLKDIV 17'd25
`else
`define LEDA led_cnt[24]
`define LEDB led_cnt[23]
`define CLKDIV 17'd125_000
`endif
module lcd1602(
CLK_50MHZ,
RESET_N,
LCD_D,
LCD_E,
LCD_RS,
LCD_RW,
RED,
YELLOW
);
input CLK_50MHZ;
input RESET_N;
output [7:0] LCD_D;
output LCD_E;
output LCD_RS;
output LCD_RW;
output RED,YELLOW;
reg LCD_E,LCD_RS,LCD_RW;
reg [7:0] LCD_D;
/*内部显示地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 第一行
40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 第二行
比如第二行第一个字符的地址是40H,那么是否直接写入40H就可以
将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显
示地址时要求最高位D7恒定为高电平1所以实际写入的数据应该是
01000000B(40H)+10000000B(80H)=11000000B(C0H)
*/
reg [5:0] address;
parameter cur_inc =1'b1;
parameter cur_dec =1'b0;
parameter cur_shift =1'b1;
parameter cur_noshift =1'b0;
parameter open_display =1'b1;
parameter open_cur =1'b0;
parameter blank_cur =1'b0;
parameter shift_display =1'b1;
parameter shift_cur =1'b0;
parameter right_shift =1'b1;
parameter left_shift =1'b0;
parameter datawidth8 =1'b1;
parameter datawidth4 =1'b0;
parameter twoline =1'b1;
parameter oneline =1'b0;
parameter font5x10 =1'b1;
parameter font5x7 =1'b0;
/******************************************************************/
function [7:0] ddram; //
input [5:0] n;
begin
case(n)
6'b000_000:ddram=8'b0101_0111;//w 57
6'b000_001:ddram=8'b0110_0101;//e 65
6'b000_010:ddram=8'b0110_1100;//l 6c
6'b000_011:ddram=8'b0110_0011;//c
6'b000_100:ddram=8'b0110_1111;//o
6'b000_101:ddram=8'b0110_1101;//m
6'b000_110:ddram=8'b0110_0101;//e
6'b000_111:ddram=8'b0010_0000;//
6'b001_000:ddram=8'b0111_0100;//t
6'b001_001:ddram=8'b0110_1111;//o
6'b001_010:ddram=8'b0010_0000;//
6'b001_011:ddram=8'b0011_0011;//3
6'b001_100:ddram=8'b0111_0111;//w
6'b001_101:ddram=8'b0010_1110;//.
6'b001_110:ddram=8'b0110_0101;//e
6'b001_111:ddram=8'b0110_0101;//e65
6'b010_000:ddram=8'b0111_0000;//p 70
6'b010_001:ddram=8'b0111_0111;//w 77
6'b010_010:ddram=8'b0010_1110;//.
6'b010_011:ddram=8'b0110_0011;//c
6'b010_100:ddram=8'b0110_1111;//o
6'b010_101:ddram=8'b0110_1101;//m
6'b010_110:ddram=8'b0010_1110;//.
6'b010_111:ddram=8'b0110_0011;//c
6'b011_000:ddram=8'b0110_1110;//n
6'b011_001:ddram=8'b0010_0000;//
6'b011_010:ddram=8'b0111_0011;//s
6'b011_011:ddram=8'b0110_0100;//d
6'b011_100:ddram=8'b0110_1010;//j
6'b011_101:ddram=8'b0110_1110;//n
6'b011_110:ddram=8'b0111_0100;//t
6'b011_111:ddram=8'b0110_1100;//l
endcase
end
endfunction
/******************************************************************/
// 工作指示灯
reg [24:0] led_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N)
led_cnt <= 25'd0;
else if(`LEDA)
led_cnt <= 25'd0;
else
led_cnt <= led_cnt + 1'b1;
end
assign RED = `LEDB;
/* //16 3.125mhz
reg[3:0] div_cnt;
always @ (posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N)
div_cnt <= 4'd0;
else
div_cnt <= div_cnt + 1'b1;
end
assign div = div_cnt[3];*/
//25000 //62.5hz
reg [16:0] clkcnt;
always @ (posedge CLK_50MHZ or negedge RESET_N)
begin
if(!RESET_N)
clkcnt <= 17'd0;
else if(clkcnt == `CLKDIV) //16'd25_000
clkcnt <= 17'd0;
else
clkcnt <= clkcnt + 1'b1;
end
wire tc_clkcnt; //计数25000后tc_clkcnt出现一个周期的高电平,然后又是25000周期的低电平
assign tc_clkcnt=(clkcnt==`CLKDIV)? 1'b1:1'b0;
reg clkdiv; //T 为50000个clk
always @ (posedge tc_clkcnt or negedge RESET_N)
begin
if(!RESET_N)
clkdiv <= 0;
else
clkdiv <= ~clkdiv;
end
reg clk_int; //T 为clkdiv的2倍,100000个clk
always @ (posedge clkdiv or negedge RESET_N)
begin
if(!RESET_N)
clk_int <= 0;
else
clk_int <= ~clk_int;
end
assign YELLOW = clk_int;
always @ (posedge clkdiv or negedge RESET_N)
begin
if(!RESET_N)
LCD_E <= 0;
else
LCD_E <= ~LCD_E;
end
parameter IDLE =10'b0000000001;
parameter CLEAR =10'b0000000010; //清屏
parameter SETFUNCTION =10'b0000000100; //工作方式设置 1:8/1:4位数据接口;两行/一行显示;5x10/5x7点阵
parameter SWITCHMODE =10'b0000001000; //显示状态设置,显示开/关;光标开/关;闪烁开/关
parameter SETMODE =10'b0000010000; //输入方式设置,读写数据后ram地址增/减1;画面动/不动
parameter SHIFT =10'b0000100000; //光标画面滚动 画面/光标平移一位;左/右平移一位
parameter SETDDRAM1 =10'b0001000000; //设置DDRAM
parameter WRITERAM1 =10'b0010000000; //写RAM
parameter SETDDRAM2 =10'b0100000000; //设置DDRAM
parameter WRITERAM2 =10'b1000000000; //写RAM
//parameter RETURNCURSOR =14'b0000000000010; //归home位
//parameter SETCGRAM =14'b0000001000000; //设置CGRAM
//parameter READFLAG =14'b0001000000000; //读状态
//parameter READRAM =14'b1000000000000; //读RAM
reg [9:0] s_cs,s_ns;
/******************************************************************/
always @ (posedge clk_int or negedge RESET_N)
if(!RESET_N)
s_cs <= IDLE;
else
s_cs <= s_ns;
always @ (posedge clk_int )
begin
case(s_cs)
IDLE:
s_ns = CLEAR;
CLEAR:
s_ns = SETFUNCTION;
SETFUNCTION:
s_ns = SWITCHMODE;
SWITCHMODE:
s_ns = SETMODE;
SETMODE:
s_ns = SHIFT;
SHIFT:
s_ns = SETDDRAM1;
SETDDRAM1:
s_ns = WRITERAM1;
WRITERAM1:
begin
if(address<=6'b001_111)
s_ns = WRITERAM1;
else
s_ns = SETDDRAM2;
end
SETDDRAM2:
s_ns = WRITERAM2;
WRITERAM2:
begin
if(address<=6'b011_111)
s_ns = WRITERAM2;
else
s_ns = SHIFT;
end
// default: s_ns <= s_cs;
endcase
end
always @ (posedge clk_int or negedge RESET_N)
if(!RESET_N)
begin
address <= 6'b000000;
LCD_D <= 8'b00000000;
LCD_RS <= 0;
LCD_RW <= 0;
end
else
begin
case(s_ns)
IDLE:
begin
LCD_RS <= 0;LCD_RW <= 0;
LCD_D <= 8'bzzzz_zzzz;
end
CLEAR:
begin
LCD_RS<=0;LCD_RW<=0;
LCD_D<=8'b0000_0001; //清屏01 8'b0000_0001
end
SETFUNCTION:
begin
LCD_RS<=0;LCD_RW<=0; //功能设置3C 8'b0011_1100
LCD_D[7:5]<=3'b001;LCD_D[4]<=datawidth8;LCD_D[3]<=twoline;// //数据线8位,2行,5×10点阵
LCD_D[2]<=font5x10;LCD_D[1:0]<=2'b00;
end
SWITCHMODE:
begin
LCD_RS<=0;LCD_RW<=0; //显示状态开关设置0C 8'b0000_1100
LCD_D[7:3]<=5'b00001;LCD_D[2]<=open_display;////显示开,无光标,无光标闪烁
LCD_D[1]<=open_cur;LCD_D[0]<=blank_cur;
end
SETMODE:
begin
LCD_RS<=0;LCD_RW<=0; //输入方式设置06 8'b0000_0110
LCD_D[7:2]<=6'b000001;LCD_D[1]<=cur_inc;LCD_D[0]<=cur_noshift; //写入数据后光标右移,显示屏不移动
end
SHIFT:
begin
LCD_RS<=0;LCD_RW<=0; //光标画面滚动 8'b0001_0000
LCD_D[7:4]<=4'b0001;LCD_D[3]<=shift_display;//shift_cur;
LCD_D[2]<=left_shift;
LCD_D[1:0]<=2'b00;
end //光标左移1格,且AC值减1
SETDDRAM1:
begin
LCD_RS<=0;LCD_RW<=0;LCD_D<=8'b10000000; address<=6'b000000; //显示数据存储器地址80
end
WRITERAM1:
begin
if(address<=6'b001_111)
begin
LCD_RS<=1;LCD_RW<=0;
LCD_D<=ddram(address);
address<=address+1'b1;
end
else
begin
LCD_RS<=0;LCD_RW<=0;
end
end
SETDDRAM2:
begin
LCD_RS<=0;LCD_RW<=0;LCD_D<=8'b11000000; address<=6'b010_000 ;//显示数据存储器地址80+40
end
WRITERAM2:
begin
if(address<=6'b011_111)
begin
LCD_RS<=1;LCD_RW<=0;LCD_D<=ddram(address);
address <= address+1'b1;
end
else
begin
LCD_RS<=0;LCD_RW <=0;
address<=6'b000000;
end
end
endcase
end
endmodule
3、 测试仿真
// Verilog Test Bench template for design : lcd1602
//
// Simulation tool : ModelSim-Altera (Verilog)
//
`timescale 1 ps/ 1 ps
module lcd1602_vlg_tst();
// constants
// general purpose registers
//reg eachvec;
// test vector input registers
reg CLK_50MHZ;
reg RESET_N;
// wires
wire [7:0] LCD_D;
wire LCD_E;
wire LCD_RS;
wire LCD_RW;
// assign statements (if any)
lcd1602 i1 (
// port map - connection between master ports and signals/registers
.CLK_50MHZ(CLK_50MHZ),
.LCD_D(LCD_D),
.LCD_E(LCD_E),
.LCD_RS(LCD_RS),
.LCD_RW(LCD_RW),
.RESET_N(RESET_N)
);
initial
begin
CLK_50MHZ = 0;
RESET_N = 0;
#20
RESET_N = 1;
end
initial
begin
forever
#20 CLK_50MHZ = ~CLK_50MHZ;
end
endmodule
4、 测试下载文件
lcd1602.rar
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |