论坛» DIY与开源设计» 电子DIY

sdjntl的进程贴

专家
2012-12-28 13:28 1楼

PGA开发板DIY—sdjntl的进程贴

1、 LED闪烁灯、LED流水灯、LED跑马灯

2、 PLL 控制LED

3、 读取按键并控制LED灯

4、 按键防抖动控制LED灯

5、 拔码开关控制LED灯

6、 数码管静态显示

7、 数码管动态显示

8、 数码管数字时钟

9、 LCD1602的显示

10、 LCD24064的显示

11、 串口收发数据

12、 读取PS2接口

专家
2012-12-28 13:29 2楼

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、视频文件


专家
2012-12-28 13:29 3楼

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、测试下载文件

pll_prj.rar

专家
2012-12-28 13:30 4楼

3、 读取按键并控制LED灯

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

专家
2012-12-28 13:31 5楼

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

专家
2012-12-28 13:31 6楼

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

专家
2012-12-28 13:32 7楼

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

专家
2012-12-28 13:32 8楼

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

专家
2012-12-28 13:33 9楼

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

专家
2012-12-28 13:36 10楼

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

共16条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册]