PGA开发板DIY—sdjntl的进程贴
1、 LED闪烁灯、LED流水灯、LED跑马灯
2、 PLL 控制LED
4、 按键防抖动控制LED灯
5、 拔码开关控制LED灯
6、 数码管静态显示
7、 数码管动态显示
8、 数码管数字时钟
9、 LCD1602的显示
10、 LCD24064的显示
11、 串口收发数据
12、 读取PS2接口
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
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.rar1、 实验内容
拔码开关控制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
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
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
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
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