当前位置:文档之家› 深入浅出玩转FPGA代码

深入浅出玩转FPGA代码

深入浅出玩转FPGA代码
深入浅出玩转FPGA代码

EX1

`timescale 1ns / 1ps

module clkdiv(

clk,rst_n,

clk_div

);

input clk; //50MHz

input rst_n; //低电平复位信号

output clk_div; //分频信号,连接到蜂鸣器

//---------------------------------------------------

reg[19:0] cnt; //分频计数器

always @ (posedge clk or negedge rst_n) //异步复位

if(!rst_n) cnt <= 20'd0;

else cnt <= cnt+1'b1; //寄存器cnt 20ms循环计数

//----------------------------------------------------

reg clk_div_r; //clk_div信号值寄存器

always @ (posedge clk or negedge rst_n)

if(!rst_n) clk_div_r <= 1'b0;

else if(cnt == 20'hfffff) clk_div_r <= ~clk_div_r; //每20ms让clk_div_r值翻转一次assign clk_div = clk_div_r;

endmodule

EX2

`timescale 1ns / 1ps

//说明:当三个独立按键的某一个被按下后,相应的LED被点亮;

// 再次按下后,LED熄灭,按键控制LED亮灭

module sw_debounce(

clk,rst_n,

sw1_n,sw2_n,sw3_n,

led_d1,led_d2,led_d3

);

input clk; //主时钟信号,50MHz

input rst_n; //复位信号,低有效

input sw1_n,sw2_n,sw3_n; //三个独立按键,低表示按下

output led_d1,led_d2,led_d3; //发光二极管,分别由按键控制

//---------------------------------------------------------------------------

reg[2:0] key_rst;

always @(posedge clk or negedge rst_n)

if (!rst_n) key_rst <= 3'b111;

else key_rst <= {sw3_n,sw2_n,sw1_n};

reg[2:0] key_rst_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中

always @ ( posedge clk or negedge rst_n )

if (!rst_n) key_rst_r <= 3'b111;

else key_rst_r <= key_rst;

//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期

wire[2:0] key_an = key_rst_r & ( ~key_rst);

//---------------------------------------------------------------------------

reg[19:0] cnt; //计数寄存器

always @ (posedge clk or negedge rst_n)

if (!rst_n) cnt <= 20'd0; //异步复位

else if(key_an) cnt <=20'd0;

else cnt <= cnt + 1'b1;

reg[2:0] low_sw;

always @(posedge clk or negedge rst_n)

if (!rst_n) low_sw <= 3'b111;

else if (cnt == 20'hfffff) //满20ms,将按键值锁存到寄存器low_sw中cnt == 20'hfffff low_sw <= {sw3_n,sw2_n,sw1_n};

//---------------------------------------------------------------------------

reg [2:0] low_sw_r; //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中

always @ ( posedge clk or negedge rst_n )

if (!rst_n) low_sw_r <= 3'b111;

else low_sw_r <= low_sw;

//当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟周期

wire[2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);

reg d1;

reg d2;

reg d3;

always @ (posedge clk or negedge rst_n)

if (!rst_n) begin

d1 <= 1'b0;

d2 <= 1'b0;

d3 <= 1'b0;

end

else begin //某个按键值变化时,LED将做亮灭翻转if ( led_ctrl[0] ) d1 <= ~d1;

if ( led_ctrl[1] ) d2 <= ~d2;

if ( led_ctrl[2] ) d3 <= ~d3;

end

assign led_d3 = d1 ? 1'b1 : 1'b0; //LED翻转输出

assign led_d2 = d2 ? 1'b1 : 1'b0;

assign led_d1 = d3 ? 1'b1 : 1'b0;

endmodule

EX3

`timescale 1ns / 1ps

module johnson(

clk,rst_n,

key1,key2,key3,

led0,led1,led2,led3

);

input clk; //主时钟,50MHz

input rst_n; //低电平复位

input key1,key2,key3; // 按键接口

output led0,led1,led2,led3; // LED等接口

//------------------------------------

reg[23:0] delay; //延时计数器

always @ (posedge clk or negedge rst_n)

if(!rst_n) delay <= 0;

else delay <= delay+1; //不断计数,周期为320ms

reg[2:0] key_value; //键值寄存器

always @ (posedge clk or negedge rst_n)

if(!rst_n) key_value <= 3'b111;

else if(delay == 24'hffffff) key_value <= {key3,key2,key1}; //delay 320ms,锁定键值

//-------------------------------------

reg[2:0] key_value_r;

always @ (posedge clk or negedge rst_n)

if(!rst_n) key_value_r <= 3'b111;

else key_value_r <= key_value;

wire[2:0] key_change; //判定前后20ms的键值是否发生了改变,若是,则key_change置高

assign key_change = key_value_r & (~key_value); //check key_value negedge per clk

//------------------------------------

reg stop_start,left_right; //流水灯控制位

always @ (posedge clk or negedge rst_n)

if(!rst_n) begin

stop_start <= 1;

left_right <= 1;

end

else

if(key_change[2]) stop_start <= ~stop_start; //开始结束控制位

else if(key_change[1]) left_right <= 1; //流水灯方向控制

else if(key_change[0]) left_right <= 0; //流水灯方向控制

//-------------------------------------

reg[3:0] led_value_r; // LED值寄存器

always @ (posedge clk or negedge rst_n)

if(!rst_n) led_value_r <= 4'b1110;

else if(delay == 24'h3fffff && stop_start) //流水灯控制

case (left_right) //方向控制

1: led_value_r <= {led_value_r[2:0],led_value_r[3]}; //右移

0: led_value_r <= {led_value_r[0],led_value_r[3:1]}; //左移

default: ;

endcase

assign {led3,led2,led1,led0} = ~led_value_r;

endmodule

EX4

`timescale 1ns / 1ps

module led_seg7(

clk,rst_n,

sm_cs1_n,sm_cs2_n,sm_db

);

input clk; // 50MHz

input rst_n; // 复位信号,低有效

output sm_cs1_n,sm_cs2_n; //数码管片选信号,低有效

output[6:0] sm_db; //7段数码管(不包括小数点)

reg[24:0] cnt; //计数器,最大可以计数到2的25次方*20ns=640ms

always @ (posedge clk or negedge rst_n)

if(!rst_n) cnt <= 25'd0;

else cnt <= cnt+1'b1; //循环计数

reg[3:0] num; //显示数值

always @ (posedge clk or negedge rst_n)

if(!rst_n) num <= 4'd0;

else if(cnt == 24'hffffff) num <= num+1'b1; //每640ms增一

//-------------------------------------------------------------------------------

/* 共阴极:不带小数点

;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[6:0] sm_dbr; //7段数码管(不包括小数点)

always @ (num)

case (num) //NUM值显示在两个数码管上

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

assign sm_db = sm_dbr;

assign sm_cs1_n = 1'b0; //数码管1常开

assign sm_cs2_n = 1'b0; //数码管2常开

endmodule

EX5

`timescale 1ns / 1ps

module mux16(

clk,rst_n,

start,ain,bin,yout,done

);

input clk; //芯片的时钟信号。

input rst_n; //低电平复位、清零信号。定义为0表示芯片复位;定义为1表示复位信号无效。

input start; //芯片使能信号。定义为0表示信号无效;定义为1表示芯片读入输入管脚得

乘数和被乘数,并将乘积复位清零。

input[15:0] ain; //输入a(被乘数),其数据位宽为16bit.

input[15:0] bin; //输入b(乘数),其数据位宽为16bit.

output[31:0] yout; //乘积输出,其数据位宽为32bit.

output done; //芯片输出标志信号。定义为1表示乘法运算完成.

reg[15:0] areg; //乘数a寄存器

reg[15:0] breg; //乘数b寄存器

reg[31:0] yout_r; //乘积寄存器

reg done_r;

reg[4:0] i; //移位次数寄存器

//------------------------------------------------

//数据位控制

always @(posedge clk or negedge rst_n)

if(!rst_n) i <= 5'd0;

else if(start && i < 5'd17) i <= i+1'b1;

else if(!start) i <= 5'd0;

//------------------------------------------------

//乘法运算完成标志信号产生

always @(posedge clk or negedge rst_n)

if(!rst_n) done_r <= 1'b0;

else if(i == 5'd16) done_r <= 1'b1; //乘法运算完成标志

else if(i == 5'd17) done_r <= 1'b0; //标志位撤销

assign done = done_r;

//------------------------------------------------

//专用寄存器进行移位累加运算

always @(posedge clk or negedge rst_n) begin

if(!rst_n) begin

areg <= 16'h0000;

breg <= 16'h0000;

yout_r <= 32'h00000000;

end

else if(start) begin //启动运算

if(i == 5'd0) begin //锁存乘数、被乘数

areg <= ain;

breg <= bin;

end

else if(i > 5'd0 && i < 5'd16) begin

if(areg[i-1]) yout_r = {1'b0,yout[30:15]+breg,yout_r[14:1]}; //累加并移

else yout_r <= yout_r>>1; //移位不累加

end

else if(i == 5'd16 && areg[15]) yout_r[31:16] <= yout_r[31:16]+breg; //累加不移位

end

end

assign yout = yout_r;

endmodule

EX6

`timescale 1ns / 1ps

clk,rst_n,

hsync,vsync,

vga_r,vga_g,vga_b

);

input clk; //50MHz

input rst_n; //低电平复位

output hsync; //行同步信号

output vsync; //场同步信号

output vga_r;

output vga_g;

output vga_b;

//--------------------------------------------------

reg[10:0] x_cnt; //行坐标

reg[9:0] y_cnt; //列坐标

always @ (posedge clk or negedge rst_n)

if(!rst_n) x_cnt <= 11'd0;

else if(x_cnt == 11'd1039) x_cnt <= 11'd0;

else x_cnt <= x_cnt+1'b1;

always @ (posedge clk or negedge rst_n)

if(!rst_n) y_cnt <= 10'd0;

else if(y_cnt == 10'd665) y_cnt <= 10'd0;

else if(x_cnt == 11'd1039) y_cnt <= y_cnt+1'b1;

//--------------------------------------------------

wire valid; //有效显示区标志

assign valid = (x_cnt >= 11'd187) && (x_cnt < 11'd987)

&& (y_cnt >= 10'd31) && (y_cnt < 10'd631); wire[9:0] xpos,ypos; //有效显示区坐标

assign xpos = x_cnt-11'd187;

assign ypos = y_cnt-10'd31;

//--------------------------------------------------

reg hsync_r,vsync_r; //同步信号产生

always @ (posedge clk or negedge rst_n)

if(!rst_n) hsync_r <= 1'b1;

else if(x_cnt == 11'd0) hsync_r <= 1'b0; //产生hsync信号

else if(x_cnt == 11'd120) hsync_r <= 1'b1;

always @ (posedge clk or negedge rst_n)

if(!rst_n) vsync_r <= 1'b1;

else if(y_cnt == 10'd0) vsync_r <= 1'b0; //产生vsync信号

else if(y_cnt == 10'd6) vsync_r <= 1'b1;

assign hsync = hsync_r;

assign vsync = vsync_r;

//--------------------------------------------------

//显示一个矩形框

wire a_dis,b_dis,c_dis,d_dis; //矩形框显示区域定位

assign a_dis = ( (xpos>=200) && (xpos<=220) )

&& ( (ypos>=140) && (ypos<=460) );

assign b_dis = ( (xpos>=580) && (xpos<=600) )

&& ( (ypos>=140) && (ypos<=460) );

assign c_dis = ( (xpos>=220) && (xpos<=580) )

&& ( (ypos>140) && (ypos<=160) );

assign d_dis = ( (xpos>=220) && (xpos<=580) )

&& ( (ypos>=440) && (ypos<=460) );

//显示一个小矩形

wire e_rdy; //矩形的显示有效矩形区域

assign e_rdy = ( (xpos>=385) && (xpos<=415) )

&& ( (ypos>=285) && (ypos<=315) );

//--------------------------------------------------

//r,g,b控制液晶屏颜色显示,背景显示蓝色,矩形框显示红蓝色

assign vga_r = valid ? e_rdy : 1'b0;

assign vga_g = valid ? (a_dis | b_dis | c_dis | d_dis) : 1'b0;

assign vga_b = valid ? ~(a_dis | b_dis | c_dis | d_dis) : 1'b0;

endmodule

EX7

`timescale 1ns / 1ps

module speed_select(

clk,rst_n,

bps_start,clk_bps

);

input clk; // 50MHz主时钟

input rst_n; //低电平复位信号

input bps_start; //接收到数据后,波特率时钟启动信号置位

output clk_bps; // clk_bps的高电平为接收或者发送数据位的中间采样点

/*

parameter bps9600 = 5207, //波特率为9600bps

bps19200 = 2603, //波特率为19200bps

bps38400 = 1301, //波特率为38400bps

bps57600 = 867, //波特率为57600bps

bps115200 = 433; //波特率为115200bps

parameter bps9600_2 = 2603,

bps19200_2 = 1301,

bps38400_2 = 650,

bps57600_2 = 433,

bps115200_2 = 216;

*/

//以下波特率分频计数值可参照上面的参数进行更改

`define BPS_PARA 5207 //波特率为9600时的分频计数值

`define BPS_PARA_2 2603 //波特率为9600时的分频计数值的一半,用于数据采样

reg[12:0] cnt; //分频计数

reg clk_bps_r; //波特率时钟寄存器

//----------------------------------------------------------

reg[2:0] uart_ctrl; // uart波特率选择寄存器

//----------------------------------------------------------

always @ (posedge clk or negedge rst_n)

if(!rst_n) cnt <= 13'd0;

else if((cnt == `BPS_PARA) || !bps_start) cnt <= 13'd0; //波特率计数清零

else cnt <= cnt+1'b1; //波特率时钟计数启动

always @ (posedge clk or negedge rst_n)

if(!rst_n) clk_bps_r <= 1'b0;

else if(cnt == `BPS_PARA_2) clk_bps_r <= 1'b1; // clk_bps_r高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点

else clk_bps_r <= 1'b0;

assign clk_bps = clk_bps_r;

endmodule

`timescale 1ns / 1ps

module my_uart_rx(

clk,rst_n,

rs232_rx,rx_data,rx_int,

clk_bps,bps_start

);

input clk; // 50MHz主时钟

input rst_n; //低电平复位信号

input rs232_rx; // RS232接收数据信号

input clk_bps; // clk_bps的高电平为接收或者发送数据位的中间采样点

output bps_start; //接收到数据后,波特率时钟启动信号置位

output[7:0] rx_data; //接收数据寄存器,保存直至下一个数据来到

output rx_int; //接收数据中断信号,接收到数据期间始终为高电平

//----------------------------------------------------------------

reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3; //接收数据寄存器,滤波用

wire neg_rs232_rx; //表示数据线接收到下降沿

always @ (posedge clk or negedge rst_n) begin

if(!rst_n) begin

rs232_rx0 <= 1'b0;

rs232_rx1 <= 1'b0;

rs232_rx2 <= 1'b0;

rs232_rx3 <= 1'b0;

end

else begin

rs232_rx0 <= rs232_rx;

rs232_rx1 <= rs232_rx0;

rs232_rx2 <= rs232_rx1;

rs232_rx3 <= rs232_rx2;

end

end

//下面的下降沿检测可以滤掉<20ns-40ns的毛刺(包括高脉冲和低脉冲毛刺),

//这里就是用资源换稳定(前提是我们对时间要求不是那么苛刻,因为输入信号打了好几拍)

//(当然我们的有效低脉冲信号肯定是远远大于40ns的)

assign neg_rs232_rx = rs232_rx3 & rs232_rx2 & ~rs232_rx1 & ~rs232_rx0; //接收到下降沿后neg_rs232_rx置高一个时钟周期

//----------------------------------------------------------------

reg bps_start_r;

reg[3:0] num; //移位次数

reg rx_int; //接收数据中断信号,接收到数据期间始终为高电平

always @ (posedge clk or negedge rst_n)

if(!rst_n) begin

bps_start_r <= 1'bz;

rx_int <= 1'b0;

end

else if(neg_rs232_rx) begin //接收到串口接收线rs232_rx的下降沿标志信号bps_start_r <= 1'b1; //启动串口准备数据接收

rx_int <= 1'b1; //接收数据中断信号使能

end

else if(num==4'd12) begin //接收完有用数据信息

bps_start_r <= 1'b0; //数据接收完毕,释放波特率启动信号

rx_int <= 1'b0; //接收数据中断信号关闭

end

assign bps_start = bps_start_r;

//----------------------------------------------------------------

reg[7:0] rx_data_r; //串口接收数据寄存器,保存直至下一个数据来到

//----------------------------------------------------------------

reg[7:0] rx_temp_data; //当前接收数据寄存器

always @ (posedge clk or negedge rst_n)

if(!rst_n) begin

rx_temp_data <= 8'd0;

num <= 4'd0;

rx_data_r <= 8'd0;

end

else if(rx_int) begin //接收数据处理

if(clk_bps) begin //读取并保存数据,接收数据为一个起始位,8bit数据,1或2个结束位

num <= num+1'b1;

case (num)

4'd1: rx_temp_data[0] <= rs232_rx; //锁存第0bit

4'd2: rx_temp_data[1] <= rs232_rx; //锁存第1bit

4'd3: rx_temp_data[2] <= rs232_rx; //锁存第2bit

4'd4: rx_temp_data[3] <= rs232_rx; //锁存第3bit

4'd5: rx_temp_data[4] <= rs232_rx; //锁存第4bit

4'd6: rx_temp_data[5] <= rs232_rx; //锁存第5bit

4'd7: rx_temp_data[6] <= rs232_rx; //锁存第6bit

4'd8: rx_temp_data[7] <= rs232_rx; //锁存第7bit

default: ;

endcase

end

else if(num == 4'd12) begin //我们的标准接收模式下只有1+8+1(2)=11bit的有效数据

num <= 4'd0; //接收到STOP位后结束,num清零

rx_data_r <= rx_temp_data; //把数据锁存到数据寄存器rx_data中end

end

assign rx_data = rx_data_r;

endmodule

`timescale 1ns / 1ps

module my_uart_top(

clk,rst_n,

rs232_rx,rs232_tx

);

input clk; // 50MHz主时钟

input rst_n; //低电平复位信号

input rs232_rx; // RS232接收数据信号

output rs232_tx; // RS232发送数据信号

wire bps_start1,bps_start2; //接收到数据后,波特率时钟启动信号置位

wire clk_bps1,clk_bps2; // clk_bps_r高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点

wire[7:0] rx_data; //接收数据寄存器,保存直至下一个数据来到

wire rx_int; //接收数据中断信号,接收到数据期间始终为高电平

//----------------------------------------------------

//下面的四个模块中,speed_rx和speed_tx是两个完全独立的硬件模块,可称之为逻辑复制//(不是资源共享,和软件中的同一个子程序调用不能混为一谈)

////////////////////////////////////////////

speed_select speed_rx(

.clk(clk), //波特率选择模块

.rst_n(rst_n),

.bps_start(bps_start1),

.clk_bps(clk_bps1)

);

my_uart_rx my_uart_rx(

.clk(clk), //接收数据模块

.rst_n(rst_n),

.rs232_rx(rs232_rx),

.rx_data(rx_data),

.rx_int(rx_int),

.clk_bps(clk_bps1),

.bps_start(bps_start1)

);

///////////////////////////////////////////

speed_select speed_tx(

.clk(clk), //波特率选择模块

.rst_n(rst_n),

.bps_start(bps_start2),

.clk_bps(clk_bps2)

);

my_uart_tx my_uart_tx(

.clk(clk), //发送数据模块

.rst_n(rst_n),

.rx_data(rx_data),

.rx_int(rx_int),

.rs232_tx(rs232_tx),

.clk_bps(clk_bps2),

.bps_start(bps_start2)

);

`timescale 1ns / 1ps

module my_uart_tx(

clk,rst_n,

rx_data,rx_int,rs232_tx,

clk_bps,bps_start

);

input clk; // 50MHz主时钟

input rst_n; //低电平复位信号

input clk_bps; // clk_bps_r高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点

input[7:0] rx_data; //接收数据寄存器

input rx_int; //接收数据中断信号,接收到数据期间始终为高电平,在该模块中利用它的下降沿来启动串口发送数据

output rs232_tx; // RS232发送数据信号

output bps_start; //接收或者要发送数据,波特率时钟启动信号置位

//---------------------------------------------------------

reg rx_int0,rx_int1,rx_int2; //rx_int信号寄存器,捕捉下降沿滤波用

wire neg_rx_int; // rx_int下降沿标志位

always @ (posedge clk or negedge rst_n) begin

if(!rst_n) begin

rx_int0 <= 1'b0;

rx_int1 <= 1'b0;

rx_int2 <= 1'b0;

end

else begin

rx_int0 <= rx_int;

rx_int1 <= rx_int0;

rx_int2 <= rx_int1;

end

end

assign neg_rx_int = ~rx_int1 & rx_int2; //捕捉到下降沿后,neg_rx_int拉高保持一个主时钟周期

//---------------------------------------------------------

reg[7:0] tx_data; //待发送数据的寄存器

//---------------------------------------------------------

reg bps_start_r;

reg tx_en; //发送数据使能信号,高有效

always @ (posedge clk or negedge rst_n) begin

if(!rst_n) begin

bps_start_r <= 1'bz;

tx_en <= 1'b0;

tx_data <= 8'd0;

end

else if(neg_rx_int) begin //接收数据完毕,准备把接收到的数据发回去bps_start_r <= 1'b1;

tx_data <= rx_data; //把接收到的数据存入发送数据寄存器

tx_en <= 1'b1; //进入发送数据状态中

end

else if(num==4'd11) begin //数据发送完成,复位

bps_start_r <= 1'b0;

tx_en <= 1'b0;

end

end

assign bps_start = bps_start_r;

//---------------------------------------------------------

reg rs232_tx_r;

always @ (posedge clk or negedge rst_n) begin

if(!rst_n) begin

num <= 4'd0;

rs232_tx_r <= 1'b1;

end

else if(tx_en) begin

if(clk_bps) begin

num <= num+1'b1;

case (num)

4'd0: rs232_tx_r <= 1'b0; //发送起始位

4'd1: rs232_tx_r <= tx_data[0]; //发送bit0

4'd2: rs232_tx_r <= tx_data[1]; //发送bit1

4'd3: rs232_tx_r <= tx_data[2]; //发送bit2

4'd4: rs232_tx_r <= tx_data[3]; //发送bit3

4'd5: rs232_tx_r <= tx_data[4]; //发送bit4

4'd6: rs232_tx_r <= tx_data[5]; //发送bit5

4'd7: rs232_tx_r <= tx_data[6]; //发送bit6

4'd8: rs232_tx_r <= tx_data[7]; //发送bit7

4'd9: rs232_tx_r <= 1'b1; //发送结束位

default: rs232_tx_r <= 1'b1;

endcase

end

else if(num==4'd11) num <= 4'd0; //复位

end

end

assign rs232_tx = rs232_tx_r;

endmodule

EX8

`timescale 1ns / 1ps

module my_uart_tx(clk,rst_n,clk_bps,rx_data,rx_int,rs232_tx,bps_start);

input clk; // 50MHz主时钟

input rst_n; //低电平复位信号

input clk_bps; // clk_bps的高电平为接收或者发送数据位的中间采样点

input[7:0] rx_data; //接收数据寄存器

input rx_int; //接收数据中断信号,接收到数据期间始终为高电平,在此利用它的上升沿来启动发送数据

output rs232_tx; // RS232发送数据信号

output bps_start; //接收或者要发送数据,波特率时钟启动信号置位

//---------------------------------------------------------

reg rx_int0,rx_int1,rx_int2; //rx_int信号寄存器,捕捉下降沿滤波用

wire pos_rx_int; // rx_int下降沿标志位

always @ (posedge clk or negedge rst_n) begin

if(!rst_n) begin

rx_int0 <= 1'b0;

rx_int1 <= 1'b0;

rx_int2 <= 1'b0;

end

else begin

rx_int0 <= rx_int;

rx_int1 <= rx_int0;

rx_int2 <= rx_int1;

end

end

assign pos_rx_int = rx_int1 & ~rx_int2; //捕捉到上升沿后,neg_rx_int拉地保持一个主时钟周期

//---------------------------------------------------------

reg[7:0] tx_data; //待发送数据的寄存器

//---------------------------------------------------------

reg bps_start_r;

reg tx_en; //发送数据使能信号,高有效

reg[3:0] num;

always @ (posedge clk or negedge rst_n) begin

if(!rst_n) begin

bps_start_r <= 1'bz;

tx_en <= 1'b0;

tx_data <= 8'd0;

end

else if(pos_rx_int) begin //接收数据完毕,准备把接收到的数据发出去bps_start_r <= 1'b1;

tx_data <= rx_data; //把接收到的数据存入发送数据寄存器

tx_en <= 1'b1; //进入发送数据状态中

end

else if(num==4'd11) begin //数据发送完成,复位

bps_start_r <= 1'b0;

tx_en <= 1'b0;

end

end

assign bps_start = bps_start_r;

//---------------------------------------------------------

reg rs232_tx_r;

always @ (posedge clk or negedge rst_n) begin

if(!rst_n) begin

num <= 4'd0;

rs232_tx_r <= 1'b1;

end

else if(tx_en) begin

if(clk_bps) begin

num <= num+1'b1;

case (num)

4'd0: rs232_tx_r <= 1'b0; //发送起始位

4'd1: rs232_tx_r <= tx_data[0]; //发送bit0

4'd2: rs232_tx_r <= tx_data[1]; //发送bit1

4'd3: rs232_tx_r <= tx_data[2]; //发送bit2

4'd4: rs232_tx_r <= tx_data[3]; //发送bit3

4'd5: rs232_tx_r <= tx_data[4]; //发送bit4

4'd6: rs232_tx_r <= tx_data[5]; //发送bit5

4'd7: rs232_tx_r <= tx_data[6]; //发送bit6

4'd8: rs232_tx_r <= tx_data[7]; //发送bit7

4'd9: rs232_tx_r <= 1'b1; //发送结束位

default: rs232_tx_r <= 1'b1;

endcase

end

else if(num==4'd11) num <= 4'd0; //复位

end

end

assign rs232_tx = rs232_tx_r;

endmodule

`timescale 1ns / 1ps

module ps2_key(clk,rst_n,ps2k_clk,ps2k_data,rs232_tx);

input clk; //50M时钟信号

input rst_n; //复位信号

input ps2k_clk; //PS2接口时钟信号

input ps2k_data; //PS2接口数据信号

output rs232_tx; // RS232发送数据信号

wire[7:0] ps2_byte; // 1byte键值

wire ps2_state; //按键状态标志位

wire bps_start; //接收到数据后,波特率时钟启动信号置位

wire clk_bps; // clk_bps的高电平为接收或者发送数据位的中间采样点

ps2scan ps2scan( .clk(clk), //按键扫描模块

.rst_n(rst_n),

.ps2k_clk(ps2k_clk),

.ps2k_data(ps2k_data),

.ps2_byte(ps2_byte),

.ps2_state(ps2_state)

);

speed_select speed_select( .clk(clk),

.rst_n(rst_n),

.bps_start(bps_start),

.clk_bps(clk_bps)

);

my_uart_tx my_uart_tx( .clk(clk),

.rst_n(rst_n),

.clk_bps(clk_bps),

.rx_data(ps2_byte),

.rx_int(ps2_state),

.rs232_tx(rs232_tx),

.bps_start(bps_start)

);

endmodule

`timescale 1ns / 1ps

module ps2scan(clk,rst_n,ps2k_clk,ps2k_data,ps2_byte,ps2_state);

input clk; //50M时钟信号

input rst_n; //复位信号

input ps2k_clk; //PS2接口时钟信号

input ps2k_data; //PS2接口数据信号

output[7:0] ps2_byte; // 1byte键值,只做简单的按键扫描

output ps2_state; //键盘当前状态,ps2_state=1表示有键被按下

//------------------------------------------

reg ps2k_clk_r0,ps2k_clk_r1,ps2k_clk_r2; //ps2k_clk状态寄存器

//wire pos_ps2k_clk; // ps2k_clk上升沿标志位

wire neg_ps2k_clk; // ps2k_clk下降沿标志位

always @ (posedge clk or negedge rst_n) begin

if(!rst_n) begin

ps2k_clk_r0 <= 1'b0;

ps2k_clk_r1 <= 1'b0;

ps2k_clk_r2 <= 1'b0;

end

else begin //锁存状态,进行滤波ps2k_clk_r0 <= ps2k_clk;

ps2k_clk_r1 <= ps2k_clk_r0;

ps2k_clk_r2 <= ps2k_clk_r1;

end

end

assign neg_ps2k_clk = ~ps2k_clk_r1 & ps2k_clk_r2; //下降沿

//------------------------------------------

reg[7:0] ps2_byte_r; //PC接收来自PS2的一个字节数据存储器

fpga数字钟课程设计报告

f p g a数字钟课程设计报告 Prepared on 24 November 2020

课程设计报告 设计题目:基于FPGA的数字钟设计 班级:电子信息工程1301 姓名:王一丁 指导教师:李世平 设计时间:2016年1月 摘要 EDA(Electronic Design Automation)电子设计自动化,是以大规模可编程器件为设计载体,以硬件描述语言为系统逻辑描述的主要表达方式,通过相关的软件,自动完成软件方式设计得电子系统到硬件系统,最终形成集成电子系统或专用集成芯片。本次课程设计利用Quartus II 为设计软件,VHDL为硬件描述语言,结合所学知识设计一个多功能时钟,具有显示年、月、日、时、分、秒显示,计时,整点报时,设定时间等功能。利用硬件描述语言VHDL 对设计系统的各个子模块进行逻辑描述,采用模块化的思想完成顶层模块的设计,通过软件编译、逻辑化简、逻辑综合优化、逻辑仿真、最终完成本次课程设计的任务。 关键词:EDA VHDL语言数字钟 目录 摘要 1 课程设计目的 2 课程设计内容及要求

设计任务 设计要求 3 VHDL程序设计 方案论证 系统结构框图 设计思路与方法 状态控制模块 时分秒模块 年月日模块 显示模块 扬声器与闹钟模块 RTL整体电路 4 系统仿真与分析 5 课程设计总结,包括.收获、体会和建议 6 参考文献 1 课程设计目的 (1)通过设计数字钟熟练掌握EDA软件(QUARTUS II)的使用方法,熟练进行设计、编译,为以后实际工程问题打下设计基础。 (2)熟悉VHDL 硬件描述语言,提升分析、寻找和排除电子设计中常见故障的能力。 (3)通过课程设计,锻炼书写有理论根据的、实事求是的、文理通顺的课程设计报告。

FPGA设计的报告课程设计

FPGA课程设计 实 验 报 告

实验一:设计一个可控的100进制可逆计数器 一、实验要求 用DE2-115开发板下载。 (1)计数器的时钟输入信号周期为200ns。 (2)以十进制形式显示。 (3)有一个复位端clr和两个控制端plus和minus,在这些控制信号的作用 clr plus minus 功能 0 ××复位为0 1 1 0 递增计数 1 0 1 递减计数 1 1 1 暂停计数 二、关键词 可控制、可逆、100进制、复位、暂停、递增、递减 三、内容摘要 module updown_count(qout,reset,clk,plus,minus); output[7:0] qout;/*定义一个8位的输出,其目的是 低四位和高四位分别表示计数器的个位和十位。*/ input clk,plus,minus,reset;//定义四个输入,时钟,加计数,减计数和清零 reg[7:0] qout;//qout的数据类型为寄存器型 always @(posedge clk)//当clk上升沿到来时执行一遍下列程序 begin if(!reset) qout<=0;//当reset为低电平时,计数器执行清零功能,否则跳过else begin case({minus,plus})//case语句模块,包含加,减和暂停四个模块 2'b10: if (qout[3:0]==0)//判断个位是否为零,若不为零,跳到个位减一begin qout[3:0]<=9;//给个位赋值 if(qout[7:4]==0) qout[7:4]<=9;//判断十位是否为零,并且给十位赋值 else qout[7:4]<=qout[7:4]-1;//由于个位赋9,相当于向十位借一,因而十位减一end else qout[3:0]<=qout[3:0]-1;//个位减一 /*这一部分是减计数模块,其思路是:首先判断个位是否为零,若为零,则执行后面的程序,个位直接赋9,并且十位减一;否则个位减一*/ 2'b01: if (qout[3:0]==9)//判断个位是否为9,否则跳到个位加一begin

FPGA课程设计报告

F P G A 课 程 设 计 报 告 学部:信息科学与技术学部 专业:通信工程 班级:10级1班 学号:100103011125 姓名:万洁 指导老师:祝宏 合作伙伴:张紫君 2012.12.13

一.《任务书》: 实验一100进制的可逆计数器(11——12周)实验二交通灯控制系统(15周) 实验三多功能数字钟系统(14-15周)二.实验书写格式: 一:题目要求 二:程序代码 三:操作步骤及运行结果截图 四:心得体会 三.实验附录: 一:老师提供的资源 二:关于实验所用EP4CE115F29板的简介

实验一100进制的可逆计数器 一、设计一个可控的100进制可逆计数器,要求用实验箱下载。 (1)计数器的时钟输入信号周期为200ns。 (2)以十进制形式显示。 (3)有一个复位端clr和两个控制端plus和minus,在这些控制信号的作用下,计数器具有复位、增或减计数、暂停功能。 clr plus minus 功能 0 ××复位为0 1 1 0 递增计数 1 0 1 递减计数 1 1 1 暂停计数 二、程序如下: module keni100(CLR,CLK,PLUS,MINUS,OUT); //100进制的可逆计数器 input CLR,PLUS,MINUS,CLK; output [7:0]OUT; reg [7:0]OUT; always@(posedge CLK) begin if(!CLR) //如果CLR为零,输出为零;反之,运行else程序 OUT[7:0]<=0; else

begin if(PLUS==0 && MINUS==1) //100进制的递减计数 begin if (OUT[3:0]==0) begin OUT[3:0]<=9; if (OUT[7:4]==0) OUT[7:4]<=9; else OUT[7:4]<=OUT[7:4]-1; end else OUT[3:0]<=OUT[3:0]-1; end if(PLUS==1 && MINUS==0) //100进制的递增计数 begin if (OUT[3:0]==9) begin OUT[3:0]<=0; if (OUT[7:4]==9) OUT[7:4]<=0; else OUT[7:4]<=OUT[7:4]+1; end else OUT[3:0]<=OUT[3:0]+1; end if(PLUS==1 && MINUS==1) OUT<=OUT; //若PLUS和MINUS都为1,暂停计数 if(PLUS==0 && MINUS==0) OUT<=0; //若都为零,输出为零end end endmodule 三、运行程序 1、在quarters II9.1输入程序 打开quarters II界面,点击file→New,在出现的对话框,如图1.1所示,选择Text File,点击OK.

基于FPGA的VGA显示设计报告

正文 一,VGA时序标准 VGA是一种常用的显示输出接口,采用行场扫描控制结合RGB三色合成原理,输出 显示信号。每个VGA接口为15针接口,分三行排布,每行5针。如图所示: 图1.1 VGA接口 15针并未全部使用,有效的信号线共5根,即红绿蓝三基色信号线:R,G,B,每线电压从0V到0.71V变化,表示无色到饱和,依据电平高低,显示颜色的饱和程度。行同步控制信号,Hsync,控制每行扫描像素的有效和失效。场同步:Vsync,控制场方向,即整个图像显示过程的时间长度,场同步中的显示部分的时间长度,等于每行扫描时间的总和。 在不同刷新频率下,显示每个像素的时间是不同的,相同刷新频率下,每个像素显示时间是固定的,所以,不同的每个像素写入时间,导致了分辨率的不同。因为VGA的显示是逐行扫描,每行从左到右扫描,到了行尾,回归到下一行的行头,继续向尾部扫描。所以,显示原理是逐次写入每行的像素数据,直到整幅图像显示成功为止。 VGA显示的数据是不能锁存的,所以必须一次又一次的连续输入数据,72Hz的刷新率下,一秒钟显示72幅图像,所以,需要连续写入72幅图像,才能达到一秒的显示效果。所以,VGA显示图像,要反反复复写入图像数据,才能得到持续的显示效果。 图1.2 VGA接口线序 VGA显示,无法做到类似于TFT液晶屏的定点写入,VGA是扫描式暂时显示,所以时序显得尤为重要,时序出现失误,图像会出现走形,无法达到准确效果。而显示的时序控制主要依靠两条数据通道:行同步和场同步,即Hsync和Vsync,其控制了扫描显示的起点和终点,同时控制扫描起点的时间,通过时间的控制,达到确定的显示效果。 具体的控制时序图如下:

FPGA课程设计报告

2014年FPGA课程设计 课程设计报告 课程名称:FPGA课程设计 实验名称:直接数字合成器设计 姓名:李思彧 学号: 20114690 班级:电子科11-1 班 指导教师:倪伟 合肥工业大学电子科学与应用物理学院制

一、实验原理 直接数字式频率合成器(DDS)是将先进的数字处理理论与方法引入频率合成的一项新技术,DDS把一系列数字量形式的信号通过数/模转换器转换成模拟量形式的信号。DDS的具体工作过程是由N位相位累加器、N位加法器和N位累加寄存器组成。每来一个时钟脉冲,N位加法器将频率控制字K与N 位累加寄存器输出的累加相位数据相加,并把相加后的结果送至累加寄存器的输入端。累加寄存器一方面将上一时钟周期作用后所产生的新的相位数据反馈到加法器的输入端,使加法器在下一时钟的作用下继续与频率控制字K相加;另一方面将这个值作为取样地址送入幅度/相位转换电路,幅度/相位转换电路根据这个地址输出相应的波形数据。最后经D/A转换器和LPF将波形数据转换成所需要的模拟波形。 图1.直接数字式频率合成的基本框图 1 DDS的设计原理 DDS的原理图如图1所示。DDS实现频率合成主要是通过查表的方式进行的。正弦查询表是一个只读存储器(ROM),以相位为地址,存有1个或多个按0°~360°相位划分幅值的正弦波幅度信息。相位累加器对频率控制字进行累加运算,若需要还可以加入相位控制字,得到的结果作为正弦波查询表的地址。正弦查询表的输出为数字化正弦幅度值,通过D/A转换器转化为近似正弦波的阶梯波,

再通过低通滤波器滤除高频成分和噪声最终得到一个纯正度很高的正弦波。1.1 建模 正弦波y=sin(2πx),若以f量化的量化频率对其幅度值进行量化,一个周期可以得到M=f量化个幅度值。将这些幅度值按顺序存入到ROM。相位累加器在参考时钟的驱动下,每来1个脉冲,输出就会增加1个步长相位增量X,输出数据作为地址送入ROM中,读出对应的幅度值形成相应的波形。 1.2 参数设定 DDS输出信号频率: 其中,X为频率累加器设定值;N为相位累加器位数;fc为参考时钟频率。 例如,假定基准时钟为200 MHz,累加器的位数为32,频率控制字X 为: 0x08000000H,即为227,则: 再设定频率控制字X为0x80000000H,即为231,则: 可见,理论上通过设定DDS相位累加器位数N、频率控制字X和基准fc的值,就可以得到任一频率的输出。频率分辨率为:fres=fc/2N,由参考时钟和累加器的位数决定,当参考时钟的频率越高,相位累加器的位数越高,所得到的频率分辨率就越高。

FPGA设计报告

西安邮电学院 FPGA课程设计报告 题目:采用RAM实现计数器及FPGA功能验证 院系:电子工程学院 专业班级: 学生姓名: 导师姓名: 起止时间:2012-06-18至2012-06-29 2012年07 月01 日

FPGA课程设计报告提纲 1.任务 用一个10×8的双口RAM完成10个8位计数器,计数器的初值分别为 1~10,时钟频率为1MHz,计数器计数频率为1Hz。 用FPGA开发板上的按键作为计数器计数值的输出选择控制,数码管 (或led)作为选择计数器的计数值输出。 2.目的 采用RAM实现计数器及FPGA功能验证 3.使用环境(软件/硬件环境,设备等) 前仿modelsim 6.1f 后仿Quartus II 10.1 xilinx ise 9.1 FPGA课程设计详细内容 4.1 技术规范 功能: 1.先由复位键从选定的RAM地址中读出预置的8位初值存入计数模块。 2.由开始键开始计数,暂停键暂停计数并同时存入RAM中以选定的存储单元。 3. 双端口RAM为10×8RAM由一个地址切换键按顺序切换1~10个地址端 口。 4.读出数据开始计数暂 停计数存入数据 计数流程 5输出到数 码管显示 读取结果输出流程 6.分频:1Hz的秒计时频率,用来进行秒计时;

4.2 设计方案 信号定义: 分频:1Hz 的秒计时频率, 用来进行秒计时 分频:时钟信号clk ; 分频信号 clk_1hz ; 开始计时(使能) rst_n ; 切换端口 开始计 暂停计数 存入数据 计数:开始计数 rst_n 计数器复位 reset ; 计数输出 ain ; 计数暂停 pause ; 计数置数 reduce ;

FPGA课程设计题目

1、彩灯控制器设计 内容及要求: 设计一个彩灯控制器,具体设计要求如下: (1)要有多种花型变化(至少设计5种),led至少16路 (2)多种花型可以自动变化 (3)彩灯变换的快慢节拍可以选择 (4)具有清零开关 (5)完成全部流程:设计规范文档、模块设计、代码输入、仿真、下载验证等,最后就课程设计本身提交一篇课程设计报告。 2、数字秒表设计 内容及要求: 设计一用于体育比赛的数字秒表,具体设计要求如下: (1)6位数码管显示,其中两位显示min,四位显示see,显示分辨率为0.01 s。 (2)秒表的最大计时值为59min59.99see。 (3)设置秒表的复位/启动键,按一下该键启动计时,再按即清0。依此循环。 (4)设置秒表的暂行/继续键。启动后按一下暂行,再按继续。依此循环。 (5)完成全部流程:设计规范文档、模块设计、代码输入、仿真、下载验证等,最后就课程设计本身提交一篇课程设计报告。 3、交通信号控制系统设计 内容及要求: 设计一个十字路口交通控制系统,具体设计要求如下: (1)东西(用A表示)、南北(用B表示)方向均有绿灯、黄灯、红灯指示,其持续时间分别是40秒、5秒和45秒, 交通灯运行的切换示意图和时序图分别如图1、图2所示。 (2)系统设有时钟,以倒计时方式显示每一路允许通行的时间。 (3)当东西或南北两路中任一路出现特殊情况时,系统可由交警手动控制立即进入特殊运行状态,即红灯全亮,时钟停止计时,东西、南北两路所有车辆停止通行;当特殊运行状态结束后,系统恢复工作,继续正常运行。 图1 交通灯运行切换示意图

B红 CP A绿 A黄 A红 B黄 B绿 5S 5S 图2 交通灯时序图 (4)完成全部流程:设计规范文档、模块设计、代码输入、仿真、下载验证等,最后就课程设计本身提交一篇课程设计报告。 4、简易密码锁设计 内容及要求 设计一个4位串行数字锁。 (1)开锁代码为4位二进制,当输入代码的位数与锁内给定的密码一致,且按规定程序开锁时,方可开锁,并点亮一个指示灯。否则进入“错误”状态,并发出报警信号。 (2)锁内的密码可调,且预置方便,保密性好。 (3)串行数字锁的报警由点亮一个灯,直到按下复位开关,报警才停下。此时,数字锁又自动等待下一个开锁状态。 (4)完成全部流程:设计规范文档、模块设计、代码输入、仿真、下载验证等,最后就课程设计本身提交一篇课程设计报告。 5、出租车计价器设计 内容及要求 (1)设一个出租车自动计费器,计费包括起步价、行驶计费和等待计费三个部分,用4个数码管显示出金额数目,最大值为999.9元,最小计价单位为0.1元。行驶里程在3公里范围内且等待时间未超过三分钟时按起步价8元计费;行驶里程超过三公里后按每公里2元收费;等待时间超过三分钟后按每分钟1元收费。等待时间用两个数码管显示,最大值为59分钟。 总费用=起步价+(里程-3km )*里程单价+(等待时间-3)*等候单价 (2)能够实现的功能: 显示汽车行驶里程:用四位数字显示,单位为km 。 计程范围为0~99km ,计程分辨率为1km 。 显示等候时间:用两位数字显示分钟,单位为min 。计时范围为0~59min ,计时分辨率为1min 。

数字电路与逻辑设计实验报告,基于FPGA的数字电子钟的设计与实现

学生实验实习报告册 学年学期: 课程名称: 实验项目:基于FPGA的数字电子钟的设计与实现 姓名: 学院和专业: 班级: 指导教师: 重庆邮电大学教务处制

1.系统顶层模块设计(如:图一 0) 图一0

2.主要功能模块电路设计 2.1分频模块 这是分频模块的顶层设计图主要完成了把50MHz的时钟信号降频为1KHz、500Hz、1Hz 图一 1 图一 1 这是其中100分频计数器的计数器图一 2 图一 2 2.2计时模块 分、秒计时模块(实现模60计数)图二 1 这是两个模60计数器, 图二 1

其中是连在一起的,把秒钟的进位信号接到分钟计数模块的接收端 2.2.1小时计时模块(实现模24计数图二 2) 这是模24计数器(如图:图二 2),是用74390来实现,47390 是下降沿有效 图二 2 2.3数码管动态显示模块 这是动态显示模块的顶层设计图,如图:图二 3 图二 3 2.3.1扫描模块couner6(实现6位数码管的扫描图二 4) 该模块需使用74390设计一个模6的计数器。实现了模值为6的计数功能其中应该接好 global 用作延时

图二 4 位选模块dig_select(3-8译码器用作控制哪一个数码显示器亮) 图二 5 该模块用于选择 6位数码管中的某一位显示相应字形。74138为 图二 5 2.3.2段选模块seg_select 图二 6 该模块功能是从6组4bit信号中选择一组作输出。 图二 6

2.3.3译码模块decoder(实现了把8421码,译码成数码管的显示)图二 7 图二 7 2.4整点报时 设计思路:首先要做到在整点的时候报时(也就是说再整点的时候蜂鸣器响),那么我们就观察在整点的时候电路有什么特征。 我们观察到的特征就是:在整点的时候秒钟,分钟都是为零的,也就是说在正点的时候分钟秒钟的二进制数每位都是为零的,那么这就是我们控制蜂鸣器响的条件了。那就是把秒钟分钟的每个线或非一下就好了。但是我们要实现蜂鸣器响几秒,那么就再秒钟的低两位上就不接,就实现了响四秒。 图三 1 2.5调时功能 在设计调时间功能的时候,首先就想到我们直接在计数器的cp信号上接上一个开关然后手动给cp然后计数器增加,但是我们在不用调时的时候就是正常的时钟,那么我们就用一个二选一数选器来实现选择计数器的cp信号的来自我们手动给还是来自上一个计数器的进位信号。

武汉理工大学 FPGA综合设计报告

附件1: 学号:0121109320426 课程设计 题目DAC0832接口电路及程序设计 学院信息工程学院 专业通信工程 班级通信1104班 姓名张亚男 指导教师陈适 2014年6 月18日

课程设计任务书 学生姓名:张亚男专业班级:通信1104班 指导教师:陈适工作单位:信息工程学院 题目: DAC0832接口电路及程序设计 初始条件: VHDL程序设计及Quartus II仿真 要求完成的主要任务: (包括课程设计工作量及技术要求,以及说明书撰写等具体要求) 1、根据DAC0832 输出控制时序,利用接口电路图,通过改变输出数据设计一个锯齿 波发生器。 2、DAC0832是8位的D/A转换器,转换周期为1μs。 3、锯齿波形数据可以由256个点构成,每个点的数据长度为8位。 4、因为FPGA的系统时钟为50MHz,必须对其进行分频处理,这里进行64分频,得到 的锯齿波的频率为762.9Hz。 时间安排: 1、2014年6 月14 日,布置课设具体实施计划与课程设计报告格式的要求说明。 2、2014年6 月14 日至2014年6 月15 日,方案选择和电路设计。 3、2014年6 月16 日至2014年6 月17 日,电路调试和设计说明书撰写。 4、2014年6 月18 日,上交课程设计成果及报告,同时进行答辩。 指导教师签名:年月日 系主任(或责任教师)签名:年月日

目录 摘要....................................................... 错误!未定义书签。Abstract.................................................... 错误!未定义书签。 1 设计原理................................................. 错误!未定义书签。 1.1 DAC0832的功能描述.................................. 错误!未定义书签。 1.1.1 DAC0832的主要功能 (1) 1.1.2 DAC0832的引脚功能 (1) 1.1.3 DAC0832的内部结构 (2) 1.1.4 DAC0832的工作时序 .............................. 错误!未定义书签。 1.2 FPGA与DAC0832的接口电路 (4) 1.3 DAC0832输出控制时序................................ 错误!未定义书签。 2 VHDL程序设计........................................... 错误!未定义书签。 2.1 设计任务 (7) 2.2 DAC0832接口电路程序符号图 (7) 2.3 VHDL程序 (7) 3 程序仿真及分析........................................... 错误!未定义书签。 3.1 QuartusⅡ软件简介 (9) 3.1.1 QuartusⅡ软件开发环境及基本流程 (9) 3.1.2 具体设计流程 (11) 3.2 仿真结果及分析 (13) 4 总结及体会 (14) 5.参考文献 (15)

课程设计报告FPGA

课程设计报告 自动售货机 学院:电子与通信工程学院 班级:微电子1班 姓名:刁飞鹏 学号:09110038

自动售货机设计 任务分析 任务要求利用开发系统板,设计一个自动售货机控制芯片。自动售货机平时处于待机状态,当有钱投入之后开始工作。利用三个按键作为投币信号,分别代表投币5元、10元、20元,投入钱币以后,采用七段数码管显示投入的金额;利用另外4个按键代表4种货物,可以在售货机上选择购买的货物,假设4种货物的售价分别为3元、6元、10元、17元。选择了货物之后,七段数码管显示购物之后的找币余额,并且用LED数码管指示灯显示是否有足够的金额购买,如果投币不够,报警指示灯亮起,并且显示余额为零。选择了购买物品之后,可以按键出货或者余额不足退币。 系统的输入信号包括8个按键开关、时钟信号,输出部分有2个LED、4个七段数码管,系统框图如图所示。 自动售货机控制芯片的外部时钟由晶振产生,该开发板系统实例中晶振频率为50Mhz。

系统设计 自动售货机控制芯片系统结构框图如图所示,包括三个模块:分频器模块、核心控制模块和按键与七段数码管控制模块。其中,分频器模块主要用于产生供按键、七段数码管扫描的时钟,这个扫描时钟的周期应该大约为0.01~0.001&同时,这个分频时钟也可用于核心模块的基本控制,由于扫描时钟要和按键、七段数码管控制电路构成一个同步电路,因此,必须使用同一个分频时钟。 核心控制模块的作用主要是控制系统的状态。系统一共有三种状态,需要使用两位状态寄存器存储状态数据,每个状态之间的转换由外部按键控制,在每一个状态下,有不同的七段数码管和指示灯的输出。 按键和数码管显示控制电路是对外部的矩阵按键以及动态显示硬 件进行驱动,该模块对矩阵按键进行扫描,输出经过扫描之后的按 键结果。并且可以把核心模块输出的二进制显示数据转化为BCD码, 通过BCD译码,以及动态显示技术最终输出到动态七段数码管上显

FPGA硬件电子琴电路设计实验报告

. FPGA实验报告 题目:硬件电子琴电路设计 一.实验目的:学习利用数控分频器设计硬件电子琴实验。 二.实验原理及内容:主系统由3个模块组成,顶层设计文件中包含三个功能模块,Speakera.v 和ToneTaba.v ,NoteTabs.v 。 模块ToneTaba是音阶发生器,当8位发声控制输入Index中某一位为高电平时,则对应某一音阶的数值将从端口Tone输出,作为获得该音阶的分频预置值;同时由Code 输出对应该音阶简谱的显示数码,如‘5’,并由High输出指示音阶高8度显示。 模块Speakera中的主要电路是一个数控分频器,它由一个初值可预置的加法计数器构成,当模块Speakera由端口Tone获得一个2进制数后,将以此值为计数器的预置数,对端口Clk12MHZ输入的频率进行分频,之后由Spkout向扬声器输出发声。 增加一个NoteTabs模块用于产生节拍控制(Index数据存留时间)和音阶选择信号,即在NoteTabs模块放置一个乐曲曲谱真值表,由一个计数器的计数值来控制此真值表的输出,而由此计数器的计数时钟信号作为乐曲节拍控制信号,从而可以设计出一个纯硬件的乐曲自动演奏电路。 图1 硬件电子琴电路结构 三.实验步骤. 1.在QUARTUSII软件下创建一工程,工程名为songer,芯片名为EP2C35F672C6; 2.输入数控分频器程序并命名为Speakera.v,保存与工程相同的文件夹中。

. 其功能仿真波形和时序仿真波形分别如下: 3.输入音阶发生器程序并命名为ToneTaba.v ,保存与工程相同的文件夹中。 PreClk<=1'b0; Count4<=Count4+4'b1; end end always@(posedge PreClk)begin if(Count11>=11'h7FF) begin Count11<=Tone; FullSpkS<=1'b1; end else begin PreClk<=1'b1; Count4<=1;end else begin Count11<=Count11+11'b1; FullSpkS<=0; end end always@(posedge FullSpkS)begin Count2<=~Count2; if(Count2==1'b1) SpkS<=1'b1; else SpkS<=1'b0; end endmodule Module ToneTaba (Index,Code,High,Tone); input[3:0] Index; output[3:0] Code; output High; output[10:0] Tone; reg[3:0] Code=0; reg High=0; reg[10:0] Tone=0; always begin case(Index) 4'b0000 :begin Tone<=11'b11111111111; Code<=4'b0000;High<=1'b0;end//2047 4'b0001 :begin Tone<=11'b01100000101; Code<=4'b0001;High<=1'b0;end//773 4'b0010 :begin Tone<=11'b01110010000; Code<=4'b0010;High<=1'b0;end//912

fpga课程设计报告

第一部分 EDA技术的仿真 1、奇偶校验位产生器 1.1奇偶校验位的技术要求 奇偶校验是通信中常用的一种数据校验方式,试设计一个奇偶校验位产生器,根据输入字节(8位)产生相应的奇偶校验位(1的个数为奇数时输出低电平,即奇校验位为1)和偶校验位(1的个数为偶数时输出高电平,即偶校验位为1) 1.2奇偶校验位的原理 通过计算数据中“1”的个数是奇数还是偶数来判断数据的正确性。在被校验的数据后加一位校验位或校验字符用作校验码实现校验。 其生成方法是: 奇校验:确保整个被传输的数据中“1”的个数是奇数个,即载荷数据中“1”的个数是奇数个时校验位填“0”,否则填“1”; 偶校验:确保整个被传输的数据中“1”的个数是偶数个,即载荷数据中“1”的个数是奇数个时校验位填“1”,否则填“0”。 1.3奇偶校验位的功能及其仿真波形 奇偶校验位的功能具体见下表所示: 输入8位的二进制序列奇校验位 even 偶校验位 odd 1 1 0 1 0 0 1 1 1 0 1 0 0 0 1 1 1 0 0 1 其具体实现程序如下所示: module parity(data,odd,even); input [0:7]data; output odd,even; assign odd=^data; assign even=~odd; endmodule 根据程序我们得到如下的仿真波形: 图1 奇偶校验位仿真波形 中国计量学院信息工程学院课程设计报告P.2

2、十六位数据选择器 2.1数据选择器的原理 在多路数据传送过程中,能够根据需要将其中任意一路选出来的电路,叫做数据选择器,数据选择器(MUX)的逻辑功能是在地址选择信号的控制下,从多路数据中选择一路数据作为输出信号。 在数据选择器中,我们设定一个控制输入端ENA ,当ENA=1时,电路不能工作,输出Y=0;而当ENA=0时,电路才处于工作状态。由于我们设计的是16选1数据选择器,因而其有4个数据控制端,即S0,S1,S2,S3,根据这4个控制端的状态有选择性的输出。 2.2数据选择器的实现电路图 我们知道一个16选1的数据选择器是由5个4选1的数据选择器组成的,4选1的基本电路如下图所示: W[0..3]S[1..0] ENA f mux_4 inst2 在左图中,ENA 为使能控制输入端,低 电平有效,S 为两位的数据控制端,W 为输入端,f 为输出端。有上述4选1的原理图我们可以得到16选1的原理图: W[0..3]S[1..0]ENA f mux_4 inst W[0..3]S[1..0]ENA f mux_4 inst1 W[0..3]S[1..0]ENA f mux_4 inst2 W[0..3]S[1..0]ENA f mux_4 inst3 W[0..3]S[1..0]ENA f mux_4 inst4S3\32控制端 S1\S0控制端 图2 16选1数据选择器原理图 2.3数据选择器的功能仿真

FPGA技术课程设计题目及报告模板

《FPGA技术》课程设计题目(生医专业) 设计要求: 每六人选择相同题目,独立在两周内完成,并独立完成课程设计报告上交。 学号20105305-20124482,所有重修同学完成第一题;学号20130252-20130651 完成第二题 学号20130652-20130906,完成第三题;学号20131758-20131767 完成第四题 学号20131770-20131779,完成第五题;学号20131780-20132248 完成第六题 学号20132249-20132575 完成第七题 课题一数字式竞赛抢答器 具体要求: (1)设计一个可容纳3组参赛的数字式抢答器,每组设一个按钮,供抢答使用。 (2)抢答器具有第一信号鉴别和锁存功能,使除第一抢答者外的按钮不起作用。 (3)设置一个主持人“复位”按钮。 (4)主持人复位后,开始抢答,第一信号鉴别锁存电路得到信号后,有指示灯显示抢答组别,扬声器发出1~2秒的音响。 (5)设置一个计分电路,每组开始预置10分,由主持人记分,答对一次1分,答错一次减1分。 教学提示: (1)此设计问题的关键是准确判断出第一抢答者并将其锁存,实现的方法可使用触发器或锁存器,在得到第一信号后将输入封锁,使其它组的抢答信号无效。 (2)形成第一抢答信号后,用编码、译码及数码显示电路显示第一抢答者的组别,用第一抢答信号推动扬声器发出音响。 (3)计分电路采用十进制加/减计数器、数码管显示,由于每次都是加/减10分,所以个位始终为零,只要十位、百位进行加/减运算即可。 课题二VGA Monitor显示图的控制 1.设计内容 查询在不同模式的VGA Monitor的控制时序,设置相应参数时,VGA显示不同的工作模式。 2.设计要求 (1)通过FPGA产生VGA Monitor的控制时序,并利用SignalTap了解FPGA输出VGA Timing 控制讯号; (2)通过FPGA产生棋盘格等图形,在VGA显示器上进行显示; (3)可以实现VGA上小时以下模式: 在VGA Moniter 显示1024*768 60Hz 模式;640*480 85Hz 模式;800*600 72Hz 模式

fpga设计报告模板

成绩评定表 学生姓名要强班级学号1103040113 专业 电子科学与 技术课程设计题目 曼彻斯特编解码电 路设计 评 语 组长签字: 成绩 日期20 年月日

课程设计任务书 学院信息科学与工程学院专业电子科学与技术 学生姓名要强班级学号 1103040113 课程设计题目曼彻斯特编解码电路设计 实践教学要求与任务: 工作计划与进度安排: 第1-2天:讲解题目,准备参考资料,检查、调试实验软硬件,进入设计环境,开始设计方案和验证方案的准备; 第3-5天:完成设计,经指导老师验收后进入模块电路设计(验收设计文档); 第6-9天:完成模块电路代码输入,并完成代码的仿真(验收代码与仿真结果); 第9-10天:约束设计,综合(验收约束与综合结果); 第11-12天:布局布线,完成版图(验收版图结果); 第13-14天:物理验证、后仿真,修改设计(验收物理验证结果和时序仿真结果);第15天:整理设计资料,验收合格后进行答辩。 指导教师: 201 年月日专业负责人: 201 年月日 学院教学副院长: 201 年月日

摘要 本设计实现串行NRZ码输入,manchester码输出;manchester码输入,NRZ输出。其中包括NRZ码字按照编码规则编码;解码恢复NRZ码;编码时2x时钟输入,在内部进行分频;解码时钟恢复选作;工作时钟10kHz即可;自行设计设计下载后的验证方案;完成全部流程:设计文档、模块设计、代码输入、功能仿真、约束与综合、布局布线、下载验证等。 本设计重点采用Verilog HDL描述、ModelSim进行功能仿真、QuartusII进行逻辑综合和适配下载,最后在Altera公司的Cyclone的芯片EP20Q240C8上实现并完成测试。 在此设计过程中,完整地建立了测试平台,通过8段数码管的显示与输出波形的验证,完成了功能和时序仿真,成功实现了串行NRZ码输入,曼彻斯特码输出;曼彻斯特码输入,NRZ输出。在完成本次设计的同时考虑到其实用性方面,曼彻斯特码是一种数据通讯线性码,它的每一个数据比特都是由至少一次电压转换的形式所表示的。曼彻斯特编码因此被认为是一种自定时码。自定时意味着数据流的精确同步是可行的。每一个比特都准确的在一个预先定义时间时期的时间中被传送。曼彻斯特编码已经被许多高效率且被广泛使用的电信标准所采用,例如以太网电讯标准. 曼彻斯特编码是一种超越传统数字传输的信道编码技术,由于其具有隐含时钟、去除了零频率信号的特性使得它在数据传输等领域中得到广泛的应用。 关键词曼彻斯特编解码;Verilog HDL;FPGA;仿真;综合

FPGA综合设计报告

FPGA综合设计报告

载波信号发生器设计 一、实验目的 1. 熟悉Quaturs II软件的使用。 2. 掌握正余弦查找表的用途、设计和使用方法。 3. 掌握用VerilogHDL硬件描述语言建模时序逻辑电路的能力。 二、实验内容 1.计算正余弦信号采样值 用C/C++编写程序,计算一个周期内的正余弦信号的采样值,一个周期采样32次。要求对采样值和2的幂次倍(例如16、32、64、128等)进行倍乘后处理成适当的整数值,对每个整数值进行8位二进制编码。注意:计算机中对负数用补码表示。 计算正弦信号采样值的C语言程序及注释: #include #include #include using namespace std; //C++及C 语言库函数头文件 #define PI 3.141592653 //宏定义PI数值 #define N 32 //定义放大倍数及累加变量为32,可以修改为64或者是128 int main() { double sinValue[N]; //sinValue为的抽样的数值 int outValue[N]; for(int i=0;i

FPGA课程设计报告

F P G A课程设计报告 (实现多功能数字钟) 专业班级: 07通信2班 姓名:朱绍兴 学号:0701******** 时间:2009.12.30

一、标题:设计多功能数字钟控制电路 二、任务书:用MAX+PLU SⅡ软件及Verilog HDL语言设计 一个多功能的数字钟,包括有时、分、秒的计 时,以及校时(对小时、分钟和秒能手动调整 以校准时间)、正点报时(每逢整点,产生“嘀 嘀嘀嘀-嘟”,4短一长的报时音)等附加功能。 三、关键词:24进制、60进制、正点报时、校时、数字钟 四、总体方案:多功能数字钟控制电路框图是由三部分组成 的,即秒分时控制电路、整点报时控制电路、 时段控制电路。用Verilog HDL硬件描述语 言完成编译和仿真。 五、原理框图如下: ↓ ↓ ↓

六、Verilog HDL硬件描述语言编写的功能模块: /*秒计数器m60*/ module m60(M,CP60M,CPM,RD); output [7:0]M; output CP60M; input CPM; input RD; reg [7:0]M; wire CP60M; always@(negedge RD or posedge CPM) begin if(!RD) begin M[7:0]<=0; end else begin if((M[7:4]==5)&&(M[3:0]==9)) begin M[7:0]<=0; end else begin if(M[3:0]==9) begin M[3:0]<=0; if(M[7:4]==5) begin M[7:4]<=0;end else M[7:4]<=M[7:4]+1; end

FPGA课程设计报告

FPGA课程设计报告 题目:基于CPLD的 1602字符液晶显示系统设计院系:信息与电气工程学院 班级:电子信息工程 学号: 学生姓名: 指导教师: 成绩: 2011 年7 月

基于CPLD的1602字符液晶显示系统设 计 一. 设计题目: 基于CPLD的1602 字符液晶显示系统设计 二.设计要求技术指标: 要求用1602 液晶显示字符; 显示内容:学号+英文姓名; 显示方式:流动显示,开关控制字符 流动速度及方向;具有暂停和清 屏的功能; 三.设计平台: QUARTUSII软件MARS-1270 CPLD 1602 液晶 四.设计思路与设计步骤: 液晶指令介绍: 要想控制1602 液晶显示字符,首先需要弄清 楚1602 有那些可控管脚, 有哪些控制命令,如何控制其显示,如何控制其移动及如何控制其移动速度及方 (1)接口说明:

(2)基本操作时序: A. 读状态:输入:RS=L,RW=H,E=H,输出:D B0--DB7=状态字 B.写指令:输入:RS=L,RW=L,E=下降沿脉冲, DBO--DB7=指令码, 输出:无 C.读数据:输入:RS=H,RW=H,E=H输出:, D B0--DB7=数据 D.写数据:输入:RS=H,RW=L,E=下降沿脉冲, DBO--DB7=数据, 输出:无 (3)指令集及其设置说明: A. 清屏指令: 功能:<1> 清除液晶显示器即将DDRAM的内容全部填入"空白"的ASCII码20H; <2> 光标归位,即将光标撤回液晶显示屏的左上方; <3> 将地址计数器(AC)的值设为0。 B.进入设置模式指令: 功能:设定每次定入1位数据后光标的移位方向,并且设定每次写入的一个 字符是否移动。参数设定的情况如下所示: 位名设置 I/D 0= 写入新数据后光标左移1= 写入新数据后光标右移

FPGA设计报告

上海电力学院 课程设计报告 课程设计名称:FPGA设计实践 设计课题名称:抢答器设计 班级:2007141 指导老师:赵倩、叶波姓名:高文飞学号:20072672 成绩:设计时间:19周设计地点:集成电路设计实验室 计算机信息与工程学院

抢答器设计报告 一、设计目的: 本课程的授课对象是电子科学与技术专业本科生,是电子类专业的一门重要的实践课程,是理论与实践相结合的重要环节。 本课程有助于培养学生的数字电路设计方法、掌握模块划分、工程设计思想与电路调试能力,为以后从事各种电路设计、制作与调试工作打下坚实的基础 二、实验器材和工具软件: PC机一台、QuartusII软件、DE2板。 三、设计内容: (1)抢答器可容纳四组12位选手,每组设置三个抢答按钮供选手使用。 (2)电路具有第一抢答信号的鉴别和锁存功能。在主持人将系统复位并发出抢答指令后,蜂鸣器提示抢答开始,时显示器显示初始时间并开始倒计时,若参赛选手按抢答按钮,则该组指示灯亮并用组别显示器显示选手的组别,同时蜂鸣器发出“嘀嘟”的双音频声。此时,电路具备自锁功能,使其它抢答按钮不起作用。 (3)如果无人抢答,计时器倒计时到零,蜂鸣器有抢答失败提示,主持人可以按复位键,开始新一轮的抢答。 (4)设置犯规功能。选手在主持人按开始键之前抢答,则认为犯规,犯规指示灯亮和显示出犯规组号,且蜂鸣器报警,主持人可以终止抢答执行相应惩罚。 (5)抢答器设置抢答时间选择功能。为适应多种抢答需要,系统设

有10秒、15秒、20秒和3O秒四种抢答时间选择功能。 四、设计具体步骤: 首先把系统划分为组别判断电路模块groupslct,犯规判别与抢答信号判别电路模块fgqd,分频电路模块fpq1,倒计时控制电路模块djs,显示时间译码电路模块num_7seg模块,组别显示模块showgroup 模块这六个模块,各模块设计完成后,用电路原理图方法将各模块连接构成系统。 各模块功能及代码: 1、组别判别模块 (1)功能:可容纳四组12位选手,每组设置三个抢答按钮供选手使用。若参赛选手按抢答按钮,则输出选手的组别。此时,电路具备自锁功能,使其它抢答按钮不起作用。 (2)原理:在每次时钟(50MHz)上升沿时判断按键,将按下按键的组别赋给一内部信号“h”(没有按键按下时h=“0000”),由于人的反应速度远远小于50MHz,所以可选出最先按下按键的那组。

相关主题
文本预览
相关文档 最新文档