此文章为原创出自 V3学院 www.v3edu.org,FPGA培训专家
ADC 和 DAC 是模拟量和数字量之间不可或缺的桥梁。A/D 转换器是将各种模拟信号转换为抗干扰性更强的数字信号,直接进入数字计算机进行处理。
本设计采用V3学院基础开发板,采用TCL549进行模数转换,通过数码管显示电压值。TLC549 是一个 8 位的串行模数转换器,I/O所需最大时钟为1.1MHz。A/D 转换时间最大 17us,如图1所示,TCL549引脚图,管脚8和4分别接VCC和GND,管脚1和3分别接基准电压,管脚2为输入的电压信号,管脚7为输入的控制时钟,管脚6是最后输出的8bit数字信号。本设计将管脚1和3分别接GND和vcc2.5V。
图1 TCL549引脚图
如图2,为TCL549的时序图,时钟最大为1.1Mhz;从图中可以看出当 CS 拉低时,需要保持tsu(cs)段时间,这段时间>=1.4us,之后I/O_CLOCK开始工作,数据开始传输转换,但数据传出至少保持17us,I/O_CLOCK停止工作,数据传输完成。画出visio图,如图3所示,根据visio图编写转换代码。
如图2 TCL549的时序图
如图3 TCL549的时序图
1.本设计使用1MHZ时钟,产生1MHZ时钟模块如下:
module freq(
input wire clk, //输入的系统时钟
input wire rst_n, //输入的系统复位
output reg slow_clk //输入1MHZ的慢时钟
);
reg[5:0] clk_cnt;
parameter cnt1M = 6‘d24; //1MHZ时钟计数器
always @(posedge clk or negedge rst_n)
if(!rst_n)
clk_cnt <= 0;
else if(clk_cnt == cnt1M)
clk_cnt <= 0;
else
clk_cnt <= clk_cnt + 1‘b1;
always @(posedge clk or negedge rst_n)
if(!rst_n)
slow_clk <= 0;
else if(clk_cnt == cnt1M)
slow_clk <= ~slow_clk;
endmodule
2.TCL549模数转换模块如下:
module ad(
input wire slow_clk, //输入1MHZ的慢时钟
input wire rst_n, //输入的系统复位
input wire AD_dat, //输入的TCL549转换的数据
output wire AD_CS_N, //输出给TCL549的CS断,用于启动AD转换器工作
output wire AD_CLK, //输出给TCL549的CLK断,用于AD转换器工作
output reg[11:0] out_data //传出12bit放大1000倍的电压数据
);
reg[20:0] cnt_1s; //1s计数器,使TCL549 每1s工作一次
reg flag_1s; //1s计满标志位
reg start_en; //由于数据发送前要先保持至少1.7us的时间;TCL549开始工作后,计满2us拉低
reg start_cnt; //由于数据发送前要先保持至少1.7us的时间;对2us计数
reg AD_EN; //TCL549数据转换使能;
reg[2:0] AD_cnt; //数据转换8bit计数;
reg end_en; //由于数据传输结束后,要先保持至少17us的时间进行转换;计满17us拉低
reg[4:0] end_cnt; //由于数据传输结束后,要先保持至少17us的时间进行转换;对17us计数
reg[7:0] tmp_data; //用来存储正在转换的数据;
reg[7:0] data; //用来存储转换完成后的数据;
parameter CNT1S = 21‘d999999; //1s计慢值 (999999+1)*1us
assign AD_CLK = (AD_EN==1) ? slow_clk : 1‘b0 ; //只有当数据开始转换时 AD_CLK才开始震荡,否则一直为低电平
assign AD_CS_N = (start_en | AD_EN | end_en==1) ? 1‘b0 : 1‘b1; //在TCL54工作时AD_CS一直为低;否则为高电平;
/**********************************************************************/
//1s计数器
//1s计满标志;目的为了降低TCL549刷新频率,时TCL549每秒工作一次。
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
cnt_1s <= 0;
else if(cnt_1s == CNT1S)
cnt_1s <= 0;
else
cnt_1s <= cnt_1s + 1‘b1;
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
flag_1s <= 0;
else if(cnt_1s == CNT1S)
flag_1s <= 1;
else
flag_1s <= 0;
/**********************************************************************/
//由于数据发送前要先保持至少1.7us的时间后才可以发送数据;
//计数计满2us拉低,
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
start_en <= 0;
else if(flag_1s == 1)
start_en <= 1; //1s标志位来,TCL549开始工作,开始信号拉高
else if(start_cnt==1)
start_en <= 0; //计慢2个时钟周期2us时,将开始信号拉低;
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
start_cnt <= 0;
else if(start_cnt==1)
start_cnt <= 0;
else if(start_en==1)
start_cnt <= start_cnt+1;
else
start_cnt <= 0;
/**********************************************************************/
//TCL549开始发送数据,AD_CLK开始工作,
//由于是8位AD芯片,所以只需要转换8次即可,
//及数据转换使能只需要保持8个时钟周期。
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
AD_EN <= 0;
else if(start_cnt==1 && start_en==1)
AD_EN <= 1;
else if(AD_cnt == 7) //计数器到7信号拉低,
AD_EN <= 0;
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
AD_cnt <= 0;
else if(AD_EN==1)
AD_cnt <= AD_cnt+1;
else
AD_cnt <= 0;
/**********************************************************************/
//TCL549发送数据结束后,AD_CLK停止工作,
//但需要等待至少17us数据才能输出,
//及数据转换到输出至少要保持17个时钟周期。
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
end_en <= 0;
else if(AD_cnt==7 && AD_EN==1)
end_en <= 1;
else if(end_cnt == 16)
end_en <= 0;
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
end_cnt <= 0;
else if(end_en==1)
end_cnt <= end_cnt+1;
else
end_cnt <= 0;
/**********************************************************************/
//将从TCL549读取出来的数据转换成8bit数据
//因为TCL549为8位AD芯片
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
tmp_data <= 8‘h00;
else if(AD_EN==1)
tmp_data <= {tmp_data[6:0],AD_dat};
/**********************************************************************/
//当数据转换完后保持至少17us才能把数据输出,传给data储存器。
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
data <= 8‘h00;
else if(end_cnt==16 && end_en==1)
data <= tmp_data;
/**********************************************************************/
//将8bit的数据计算成电压=(data*精度*电压最大值)/255;
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
out_data <= 11‘h00;
else
out_data <= (data*100*25)/255;
endmodule
3. 16进制转十进制BCD码代码模块如下:
module BCD_CTRL(
input wire slow_clk,
input wire rst_n,
input wire[11:0] in_data,
output reg[3:0] units,
output reg[3:0] tens,
output reg[3:0] hundreds,
output reg[3:0] thousand
);
integer i;
always @(posedge slow_clk)
begin
units = 4‘d0;
tens = 4‘d0;
hundreds = 4‘d0;
thousand = 4‘d0;
for(i=0;i<12; i=i+1)
begin
if(units>=5)
units = units +3;
if(tens>=5)
tens = tens +3;
if(hundreds>=5)
hundreds = hundreds +3;
if(thousand>=5)
thousand = thousand +3;
thousand = thousand <<1;
thousand[0] = hundreds[3];
hundreds = hundreds <<1;
hundreds[0] = tens[3];
tens = tens <<1;
tens[0] = units[3];
units = units <<1;
units[0] = in_data[11-i];
end
end
endmodule
4. 数码管显示功能代码模块如下:
module seg_play(
input wire clk , //输入的1MHZ时钟
input wire rst_n, //输入的系统复位信号
input wire[3:0] units, //显示第三个小数位;0.001v
input wire[3:0] tens , //显示第二个小数位0.01v
input wire[3:0] hundreds, //显示第一个小数位0.01v
input wire[3:0] thousand, //显示整数部分
output reg[2:0] sel, //数码管位选信号
output reg[7:0] seg //数码管段选信号
);
reg[12:0] sel_cnt;//位选刷新计数器
reg sel_en; //位选信号使能,用于显示小数点
reg[3:0] num; //用来存储要显示的数据
parameter SEL_NUM = 99; //单个数码管刷新时间;=(SEL_NUM+1)* 1us
//位选刷新计数;
always @(posedge clk or negedge rst_n)
if(!rst_n)
sel_cnt <= 0;
else if(sel_cnt==SEL_NUM)
sel_cnt <= 0;
else
sel_cnt <= sel_cnt+1;
//位选刷新,因为只有4个0--9的数据 ;故只需要点亮四个数码管即可,点亮的分别为:2号、3号、4号、5号数码管。
always @(posedge clk or negedge rst_n)
if(!rst_n)
sel <= 3‘b111;
else if(sel==5 && sel_cnt==SEL_NUM)
sel <= 3‘d2;
else if(sel_cnt==SEL_NUM)
sel <= sel + 1 ;
//数码管没刷新一个周期就将sel_en取反一次,用于显示小数点。
always @(posedge clk or negedge rst_n)
if(!rst_n)
sel_en <= 3‘b111;
else if(sel==5&&sel_cnt==SEL_NUM)
sel_en <= ~sel_en;
//传值储存,用于显示在数码管上
always @(posedge clk or negedge rst_n)
if(!rst_n)
num <= 0;
else case(sel)
3‘d2 : num <= thousand; //当数码管刷新到2号数码管时,将整数部分的数据存储在num中;
3‘d3 : num <= hundreds; //当数码管刷新到3号数码管时,将第一个小数部分的数据存储在num中;
3‘d4 : num <= tens; //当数码管刷新到4号数码管时,将第二个小数部分的数据存储在num中;
3‘d5 : num <= units; //当数码管刷新到5号数码管时,将第三个小数部分的数据存储在num中;
default:
num <= 0;
endcase
//数码管显示
always @(posedge clk or negedge rst_n)
if(!rst_n)
seg <= 8‘hff;
else if(sel_en==0&&sel==2) //当sel_en为0时,并且数码管刷新到二号数码管时,将小数点点亮;
seg <= 8‘h7f; // 本次刷新不显示整数部分;在下一次数码管刷新时显示.
else case(num) //将num存储器中的数据显示到数码管上,刚好与sel同步。
0: seg <= 8‘hc0;
1: seg <= 8‘hf9;
2: seg <= 8‘ha4;
3: seg <= 8‘hb0;
4: seg <= 8‘h99;
5: seg <= 8‘h92;
6: seg <= 8‘h82;
7: seg <= 8‘hf8;
8: seg <= 8‘h80;
9: seg <= 8‘h90;
10: seg <= 8‘h88;
11: seg <= 8‘h83;
12: seg <= 8‘hc6;
13: seg <= 8‘ha1;
14: seg <= 8‘h86;
15: seg <= 8‘h8e;
default:
seg <= 8‘hff;
endcase
endmodule
5. 顶层连线布线:
6.功能引脚绑定文件如下:
NET "seg[7]" LOC = P117;
NET "seg[6]" LOC = P121;
NET "seg[5]" LOC = P118;
NET "seg[4]" LOC = P116;
NET "seg[3]" LOC = P115;
NET "seg[2]" LOC = P114;
NET "seg[1]" LOC = P120;
NET "seg[0]" LOC = P119;
NET "sel[2]" LOC = P14;
NET "sel[1]" LOC = P15;
NET "sel[0]" LOC = P16;
NET "clk" LOC = P24;
NET "rst_n" LOC = P94;
NET "seg[7]" IOSTANDARD = LVCMOS33;
NET "seg[6]" IOSTANDARD = LVCMOS33;
NET "seg[5]" IOSTANDARD = LVCMOS33;
NET "seg[4]" IOSTANDARD = LVCMOS33;
NET "seg[3]" IOSTANDARD = LVCMOS33;
NET "seg[2]" IOSTANDARD = LVCMOS33;
NET "seg[1]" IOSTANDARD = LVCMOS33;
NET "seg[0]" IOSTANDARD = LVCMOS33;
NET "sel[2]" IOSTANDARD = LVCMOS33;
NET "sel[1]" IOSTANDARD = LVCMOS33;
NET "sel[0]" IOSTANDARD = LVCMOS33;
NET "clk" IOSTANDARD = LVCMOS33;
NET "rst_n" IOSTANDARD = LVCMOS33;
# PlanAhead Generated IO constraints
NET "AD_CLK" IOSTANDARD = LVCMOS33;
NET "AD_CS_N" IOSTANDARD = LVCMOS33;
NET "AD_dat" IOSTANDARD = LVCMOS33;
# PlanAhead Generated physical constraints
NET "AD_CLK" LOC = P126;
NET "AD_CS_N" LOC = P123;
NET "AD_dat" LOC = P124;
上板烧写,我们就实现了AD转换的过程,感谢大家对V3学院的支持,FPGA培训,就选v3学院,雄厚的师资,高深的技术,v3学院将在你的FPGA学习路上祝你一臂之力。
此文章为原创出自 V3学院 www.v3edu.org;
此文章为原创出自 V3学院 www.v3edu.org,FPGA培训专家
ADC 和 DAC 是模拟量和数字量之间不可或缺的桥梁。A/D 转换器是将各种模拟信号转换为抗干扰性更强的数字信号,直接进入数字计算机进行处理。
本设计采用V3学院基础开发板,采用TCL549进行模数转换,通过数码管显示电压值。TLC549 是一个 8 位的串行模数转换器,I/O所需最大时钟为1.1MHz。A/D 转换时间最大 17us,如图1所示,TCL549引脚图,管脚8和4分别接VCC和GND,管脚1和3分别接基准电压,管脚2为输入的电压信号,管脚7为输入的控制时钟,管脚6是最后输出的8bit数字信号。本设计将管脚1和3分别接GND和vcc2.5V。
图1 TCL549引脚图
如图2,为TCL549的时序图,时钟最大为1.1Mhz;从图中可以看出当 CS 拉低时,需要保持tsu(cs)段时间,这段时间>=1.4us,之后I/O_CLOCK开始工作,数据开始传输转换,但数据传出至少保持17us,I/O_CLOCK停止工作,数据传输完成。画出visio图,如图3所示,根据visio图编写转换代码。
如图2 TCL549的时序图
如图3 TCL549的时序图
1.本设计使用1MHZ时钟,产生1MHZ时钟模块如下:
module freq(
input wire clk, //输入的系统时钟
input wire rst_n, //输入的系统复位
output reg slow_clk //输入1MHZ的慢时钟
);
reg[5:0] clk_cnt;
parameter cnt1M = 6‘d24; //1MHZ时钟计数器
always @(posedge clk or negedge rst_n)
if(!rst_n)
clk_cnt <= 0;
else if(clk_cnt == cnt1M)
clk_cnt <= 0;
else
clk_cnt <= clk_cnt + 1‘b1;
always @(posedge clk or negedge rst_n)
if(!rst_n)
slow_clk <= 0;
else if(clk_cnt == cnt1M)
slow_clk <= ~slow_clk;
endmodule
2.TCL549模数转换模块如下:
module ad(
input wire slow_clk, //输入1MHZ的慢时钟
input wire rst_n, //输入的系统复位
input wire AD_dat, //输入的TCL549转换的数据
output wire AD_CS_N, //输出给TCL549的CS断,用于启动AD转换器工作
output wire AD_CLK, //输出给TCL549的CLK断,用于AD转换器工作
output reg[11:0] out_data //传出12bit放大1000倍的电压数据
);
reg[20:0] cnt_1s; //1s计数器,使TCL549 每1s工作一次
reg flag_1s; //1s计满标志位
reg start_en; //由于数据发送前要先保持至少1.7us的时间;TCL549开始工作后,计满2us拉低
reg start_cnt; //由于数据发送前要先保持至少1.7us的时间;对2us计数
reg AD_EN; //TCL549数据转换使能;
reg[2:0] AD_cnt; //数据转换8bit计数;
reg end_en; //由于数据传输结束后,要先保持至少17us的时间进行转换;计满17us拉低
reg[4:0] end_cnt; //由于数据传输结束后,要先保持至少17us的时间进行转换;对17us计数
reg[7:0] tmp_data; //用来存储正在转换的数据;
reg[7:0] data; //用来存储转换完成后的数据;
parameter CNT1S = 21‘d999999; //1s计慢值 (999999+1)*1us
assign AD_CLK = (AD_EN==1) ? slow_clk : 1‘b0 ; //只有当数据开始转换时 AD_CLK才开始震荡,否则一直为低电平
assign AD_CS_N = (start_en | AD_EN | end_en==1) ? 1‘b0 : 1‘b1; //在TCL54工作时AD_CS一直为低;否则为高电平;
/**********************************************************************/
//1s计数器
//1s计满标志;目的为了降低TCL549刷新频率,时TCL549每秒工作一次。
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
cnt_1s <= 0;
else if(cnt_1s == CNT1S)
cnt_1s <= 0;
else
cnt_1s <= cnt_1s + 1‘b1;
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
flag_1s <= 0;
else if(cnt_1s == CNT1S)
flag_1s <= 1;
else
flag_1s <= 0;
/**********************************************************************/
//由于数据发送前要先保持至少1.7us的时间后才可以发送数据;
//计数计满2us拉低,
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
start_en <= 0;
else if(flag_1s == 1)
start_en <= 1; //1s标志位来,TCL549开始工作,开始信号拉高
else if(start_cnt==1)
start_en <= 0; //计慢2个时钟周期2us时,将开始信号拉低;
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
start_cnt <= 0;
else if(start_cnt==1)
start_cnt <= 0;
else if(start_en==1)
start_cnt <= start_cnt+1;
else
start_cnt <= 0;
/**********************************************************************/
//TCL549开始发送数据,AD_CLK开始工作,
//由于是8位AD芯片,所以只需要转换8次即可,
//及数据转换使能只需要保持8个时钟周期。
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
AD_EN <= 0;
else if(start_cnt==1 && start_en==1)
AD_EN <= 1;
else if(AD_cnt == 7) //计数器到7信号拉低,
AD_EN <= 0;
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
AD_cnt <= 0;
else if(AD_EN==1)
AD_cnt <= AD_cnt+1;
else
AD_cnt <= 0;
/**********************************************************************/
//TCL549发送数据结束后,AD_CLK停止工作,
//但需要等待至少17us数据才能输出,
//及数据转换到输出至少要保持17个时钟周期。
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
end_en <= 0;
else if(AD_cnt==7 && AD_EN==1)
end_en <= 1;
else if(end_cnt == 16)
end_en <= 0;
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
end_cnt <= 0;
else if(end_en==1)
end_cnt <= end_cnt+1;
else
end_cnt <= 0;
/**********************************************************************/
//将从TCL549读取出来的数据转换成8bit数据
//因为TCL549为8位AD芯片
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
tmp_data <= 8‘h00;
else if(AD_EN==1)
tmp_data <= {tmp_data[6:0],AD_dat};
/**********************************************************************/
//当数据转换完后保持至少17us才能把数据输出,传给data储存器。
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
data <= 8‘h00;
else if(end_cnt==16 && end_en==1)
data <= tmp_data;
/**********************************************************************/
//将8bit的数据计算成电压=(data*精度*电压最大值)/255;
/**********************************************************************/
always @(posedge slow_clk or negedge rst_n)
if(!rst_n)
out_data <= 11‘h00;
else
out_data <= (data*100*25)/255;
endmodule
3. 16进制转十进制BCD码代码模块如下:
module BCD_CTRL(
input wire slow_clk,
input wire rst_n,
input wire[11:0] in_data,
output reg[3:0] units,
output reg[3:0] tens,
output reg[3:0] hundreds,
output reg[3:0] thousand
);
integer i;
always @(posedge slow_clk)
begin
units = 4‘d0;
tens = 4‘d0;
hundreds = 4‘d0;
thousand = 4‘d0;
for(i=0;i<12; i=i+1)
begin
if(units>=5)
units = units +3;
if(tens>=5)
tens = tens +3;
if(hundreds>=5)
hundreds = hundreds +3;
if(thousand>=5)
thousand = thousand +3;
thousand = thousand <<1;
thousand[0] = hundreds[3];
hundreds = hundreds <<1;
hundreds[0] = tens[3];
tens = tens <<1;
tens[0] = units[3];
units = units <<1;
units[0] = in_data[11-i];
end
end
endmodule
4. 数码管显示功能代码模块如下:
module seg_play(
input wire clk , //输入的1MHZ时钟
input wire rst_n, //输入的系统复位信号
input wire[3:0] units, //显示第三个小数位;0.001v
input wire[3:0] tens , //显示第二个小数位0.01v
input wire[3:0] hundreds, //显示第一个小数位0.01v
input wire[3:0] thousand, //显示整数部分
output reg[2:0] sel, //数码管位选信号
output reg[7:0] seg //数码管段选信号
);
reg[12:0] sel_cnt;//位选刷新计数器
reg sel_en; //位选信号使能,用于显示小数点
reg[3:0] num; //用来存储要显示的数据
parameter SEL_NUM = 99; //单个数码管刷新时间;=(SEL_NUM+1)* 1us
//位选刷新计数;
always @(posedge clk or negedge rst_n)
if(!rst_n)
sel_cnt <= 0;
else if(sel_cnt==SEL_NUM)
sel_cnt <= 0;
else
sel_cnt <= sel_cnt+1;
//位选刷新,因为只有4个0--9的数据 ;故只需要点亮四个数码管即可,点亮的分别为:2号、3号、4号、5号数码管。
always @(posedge clk or negedge rst_n)
if(!rst_n)
sel <= 3‘b111;
else if(sel==5 && sel_cnt==SEL_NUM)
sel <= 3‘d2;
else if(sel_cnt==SEL_NUM)
sel <= sel + 1 ;
//数码管没刷新一个周期就将sel_en取反一次,用于显示小数点。
always @(posedge clk or negedge rst_n)
if(!rst_n)
sel_en <= 3‘b111;
else if(sel==5&&sel_cnt==SEL_NUM)
sel_en <= ~sel_en;
//传值储存,用于显示在数码管上
always @(posedge clk or negedge rst_n)
if(!rst_n)
num <= 0;
else case(sel)
3‘d2 : num <= thousand; //当数码管刷新到2号数码管时,将整数部分的数据存储在num中;
3‘d3 : num <= hundreds; //当数码管刷新到3号数码管时,将第一个小数部分的数据存储在num中;
3‘d4 : num <= tens; //当数码管刷新到4号数码管时,将第二个小数部分的数据存储在num中;
3‘d5 : num <= units; //当数码管刷新到5号数码管时,将第三个小数部分的数据存储在num中;
default:
num <= 0;
endcase
//数码管显示
always @(posedge clk or negedge rst_n)
if(!rst_n)
seg <= 8‘hff;
else if(sel_en==0&&sel==2) //当sel_en为0时,并且数码管刷新到二号数码管时,将小数点点亮;
seg <= 8‘h7f; // 本次刷新不显示整数部分;在下一次数码管刷新时显示.
else case(num) //将num存储器中的数据显示到数码管上,刚好与sel同步。
0: seg <= 8‘hc0;
1: seg <= 8‘hf9;
2: seg <= 8‘ha4;
3: seg <= 8‘hb0;
4: seg <= 8‘h99;
5: seg <= 8‘h92;
6: seg <= 8‘h82;
7: seg <= 8‘hf8;
8: seg <= 8‘h80;
9: seg <= 8‘h90;
10: seg <= 8‘h88;
11: seg <= 8‘h83;
12: seg <= 8‘hc6;
13: seg <= 8‘ha1;
14: seg <= 8‘h86;
15: seg <= 8‘h8e;
default:
seg <= 8‘hff;
endcase
endmodule
5. 顶层连线布线:
6.功能引脚绑定文件如下:
NET "seg[7]" LOC = P117;
NET "seg[6]" LOC = P121;
NET "seg[5]" LOC = P118;
NET "seg[4]" LOC = P116;
NET "seg[3]" LOC = P115;
NET "seg[2]" LOC = P114;
NET "seg[1]" LOC = P120;
NET "seg[0]" LOC = P119;
NET "sel[2]" LOC = P14;
NET "sel[1]" LOC = P15;
NET "sel[0]" LOC = P16;
NET "clk" LOC = P24;
NET "rst_n" LOC = P94;
NET "seg[7]" IOSTANDARD = LVCMOS33;
NET "seg[6]" IOSTANDARD = LVCMOS33;
NET "seg[5]" IOSTANDARD = LVCMOS33;
NET "seg[4]" IOSTANDARD = LVCMOS33;
NET "seg[3]" IOSTANDARD = LVCMOS33;
NET "seg[2]" IOSTANDARD = LVCMOS33;
NET "seg[1]" IOSTANDARD = LVCMOS33;
NET "seg[0]" IOSTANDARD = LVCMOS33;
NET "sel[2]" IOSTANDARD = LVCMOS33;
NET "sel[1]" IOSTANDARD = LVCMOS33;
NET "sel[0]" IOSTANDARD = LVCMOS33;
NET "clk" IOSTANDARD = LVCMOS33;
NET "rst_n" IOSTANDARD = LVCMOS33;
# PlanAhead Generated IO constraints
NET "AD_CLK" IOSTANDARD = LVCMOS33;
NET "AD_CS_N" IOSTANDARD = LVCMOS33;
NET "AD_dat" IOSTANDARD = LVCMOS33;
# PlanAhead Generated physical constraints
NET "AD_CLK" LOC = P126;
NET "AD_CS_N" LOC = P123;
NET "AD_dat" LOC = P124;
上板烧写,我们就实现了AD转换的过程,感谢大家对V3学院的支持,FPGA培训,就选v3学院,雄厚的师资,高深的技术,v3学院将在你的FPGA学习路上祝你一臂之力。
此文章为原创出自 V3学院 www.v3edu.org;