实验内容:
一、 实验目的
1、学习用 FPGA 产生脉冲信号的方法。
2、巩固 Verilog HDL 层次化文件设计。
二、 实验内容
在遥远的 Mars 星上有一种类似地球萤火虫的生物——外星萤火虫。 外星萤火虫是社群生物,“虫后”以自己的发光信息 f0(正常时是 30%占空 比的毫秒脉冲,繁殖季为占空比为 50%,年老时占空比逐渐减小,周期逐渐增大, 直至死亡)控制整个族群的活动。虫后死亡后如果没有新的虫后及时出现,族群 成员就会四处逃散。 “信虫”负责信息中转、传达,为了使虫后的指令能够传达到整个虫族, 信虫看到虫后或者其它信虫发光时会自动同步自己的发光器,使得自己的发光 f1
与虫后的 f0 同频同相,并且自动调整发光脉冲宽度为 0.4 毫秒,以免虫族成员发 现虫后衰老而引起恐慌,保障虫族安定。 “哨虫”在虫族领地边界戍卫,哨虫看到信虫的信号会同步反馈一个防卫 信号,如果安全(sta==0),防卫信号是一个与 f1 同相的双脉冲信号 f2a(脉冲宽度
0.1 毫秒);当敌人来犯(sta==1),防卫信号是三脉冲信号 f2b(脉冲宽度 0.1 毫秒)。 哨虫离开边界地区(p=0 表示不在边界地区,p=1 表示在边界地区)会自动变 换职责为信虫。 公元 9527 年,Mars 星爆发大面积虫战,外星萤火虫伤亡惨重,现在请你 提前设计一个“电子萤火虫”,以在将来帮助外星萤火虫赢回战争。
电路要求如下:
1. f0 的频率范围是 0.5kHz~1.2kHz,占空比 1%~40%,实验时由信号发生 器产生。
2. 信虫电路的输入是 f0,输出是 f1,电路内部有 6MHz 的高精度时钟源。
3. 哨虫电路的输入是 f1 和 p,以及 sta(状态信息,0 表示安全,1 表示敌人 来犯),输出是 f2。
图 2 外星萤火虫功能仿真参考波形
4. 引脚锁定
a) CLK 锁定到 CLK0 或者 CLK1,频率设置为 6MHz;
b) f0 锁定到 ECLK(PIN_23,实验箱的外部时钟输入接口);
c) p, sta 锁定到开关上;
d) f1, f2 锁定到合适的引脚上。
5. 实验测试
a) 将函数发生器设置为矩形波输出,频率 1kHz,幅度 3.3V,偏置 1.65V。
f2a f2b
西南交通大学 电子技术实验室 数字电子技术实验
b) 将函数发生器的输出探头夹导线之后连接到实验箱的外部时钟输入 口(黑夹子接 GND,红夹子接 ECLK).
c) 改变函数发生器的输出信号频率和占空比,观测并记录 f0, f1 的波形. d) 将 f0 设置到 1kHz,分别改变 p 和 sta 的逻辑值,观察并记录不同条 件下 f0, f1 和 f2 的波形和相关参数。
6. 提高性实验内容 产生其它脉冲波形。 自拟实验方法,测量 f0,f1,f2 的延迟,并分析实验结果。
三、 预习要求
1. 完成本实验“实验内容”部分的设计任务。
2. 用 ModelSim 对实验电路进行功能仿真,用 ModelSim 的光标功能测量输 出信号的频率和高电平时间宽度,将仿真结果截图插入报告中。
3. 列出引脚锁定分配表(信号名->主板器件名->引脚号)。
4. 填写编译报告。
四、 实验报告要求
1、列出通电测试结果。
2、列出实验过程出现的问题及解决措施。
3、附源程序
设计思路:
本次实验难点在于时钟信号频数的换算,以及状态的转换。换成c语言做就是if语句判断的大模拟。首先理清逻辑:要求输出信虫和哨虫的频率,这里将他们两个分开写,目的是比较清楚。
对于信虫:题目要求脉冲宽度为0.4ms,因此我们只需要判断虫后发光信号的上升沿信息就好,对于每一个上升沿,信虫开始发光,并持续0.4ms。采用的方法是计数器。
对于哨虫:首先分为两大类:(1)哨虫不在边界区域,职能为信虫,输出频率同信虫发光信号。(2)哨虫在边界区域,分为两小类:①边界安全,则按要求输出双脉冲信号 ②边界不安全,按要求输出三脉冲信号。
代码:
设计代码:
module ovo(input clk, f0, p, sta, output reg f1, f2);
/*
clk: 6MHz
f0: 虫后的发光信号,信虫的输入
p: 位置信息:0表示不在边界地区,1表示在边界地区
sta: 状态安全信息,0表示安全,1表示敌人来犯
f1: 信虫的输出,哨虫电路的输入,f1与虫后的f0同频同相
f2: 哨虫的输出
*/
parameter N = 600;
// 0.0001s * 6,000,000/s = 600
//防卫信号的脉冲宽度是0.1毫秒,走过600个时钟信号
reg [20:0] cnt1; //信虫计数
reg [20:0] cnt2; // 哨虫计数
reg temp1; //上一clk时刻f0值
reg flag1; //f0是否为上升沿
reg temp2; // 同temp1
reg flag2; // 同flag1
//temp2 <= 1'b0;
//temp1 <= 1'b0;
// 控制信虫输出 f1
always @(posedge clk) begin
if(!temp1 & f0) flag1 <= 1'b1; // 判断f0上升沿
if(flag1) begin
if(cnt1 < 4*N) begin // 占空比为50%
f1 <= 1'b1;
cnt1 <= cnt1 + 1'b1;
end
else begin
if(cnt1 < 8*N) begin
f1 <= 1'b0;
cnt1 <= cnt1 + 1'b1;
end
else begin
f1 <= 1'b0;
cnt1 <= 21'b0;
flag1 <= 1'b0; //脉冲产生结束,标志信号置0
end
end
end
temp1 = f0; //记录状态
end
// 控制哨虫输出f2
always @(posedge clk) begin
if (!temp2 & f0) flag2 <= 1'b1; //判断f0上升沿
if (flag2) begin
casex({p, sta})
2'b0_x: begin //哨虫不在边界地区,职能为信虫
if(cnt2 < 4*N) begin // 占空比为50%
f2 <= 1'b1;
cnt2 <= cnt2 + 1'd1;
end
else if(cnt2 < 8*N) begin
f2 <= 1'b0;
cnt2 <= cnt2 + 1'd1;
end
else begin
flag2 <= 1'b0; //脉冲产生结束,标志信号置0
f2 <= 1'b0;
cnt2 <= 0;
end
end
2'b1_0: begin //哨虫在边界地区,且边界安全
if (cnt2 < N) begin
f2 <= 1'b1; //f2a的第一处高电平区
cnt2 <= cnt2 + 1'd1;
end
else if (cnt2 < 2 * N) begin
f2 <= 1'b0; //f2a的低电平区
cnt2 <= cnt2 + 1'd1;
end
else if (cnt2 < 3 * N) begin
f2 <= 1'b1; //f2a的第二处高电平区
cnt2 <= cnt2 + 1'd1;
end
else begin
f2 <= 1'b0;
cnt2 <= 21'd0;
flag2 <= 1'b0; //脉冲产生结束,标志信号置0
end
end
2'b1_1: begin //哨虫在边界地区,且边界不安全
if (cnt2 < N) begin
f2 <= 1'b1; //f2b的第一处高电平区
cnt2 <= cnt2 + 1'd1;
end
else if (cnt2 < 2 * N) begin
f2 <= 1'b0; //f2b的第一处低电平区
cnt2 <= cnt2 + 1'd1;
end
else if (cnt2 < 3 * N) begin
f2 <= 1'b1; //f2b的第二处高电平区
cnt2 <= cnt2 + 1'd1;
end
else if (cnt2 < 4 * N) begin
f2 <= 1'b0; //f2b的第二处低电平区
cnt2 <= cnt2 + 1'd1;
end
else if (cnt2 < 5 * N) begin
f2 <= 1'b1; //f2b的第三处高电平区
cnt2 <= cnt2 + 1'd1;
end
else begin
f2 <= 1'b0;
cnt2 <= 21'd0;
flag2 <= 1'b0; //脉冲产生结束,标志信号置0
end
end
endcase
end
else cnt2 <= 21'd0;
temp2 <= f0;
end
endmodule
modelsim代码:
`timescale 1ns / 1ps
module test_8();
reg clk, f0, p, sta;
wire f1, f2;
ovo fun(
.clk(clk),
.f0(f0),
.f1(f1),
.f2(f2),
.p(p),
.sta(sta)
);
initial begin
clk = 0;
f0 = 0;
p = 0;
sta = 0;
#12000000 p = 1; //12ms后由信虫模式变为哨虫模式
#10000000 sta = 1; //再10ms后敌人来犯
end
always begin //6MHz时钟信号
#83.333 clk = ~clk; #83.333 clk = ~clk; #83.334 clk = ~clk;
end
always begin
//产生虫后信号f0
//f0取1kHz
f0 = 1; #300000; //0.3ms 正常占空比为30%
f0 = 0; #700000; //0.7ms
f0 = 1; #500000; //0.5ms 繁殖季占空比为50%
f0 = 0; #500000; //0.5ms
f0 = 1; #300000; //0.3ms 正常占空比为30%
f0 = 0; #700000; //0.7ms
f0 = 1; #200000; //0.2ms 开始衰老占空比为20%
f0 = 0; #800000; //0.8ms
f0 = 1; #100000; //0.1ms 占空比为10%
f0 = 0; #900000; //0.9ms
f0 = 1; #50000; //0.5ms 占空比为5%
f0 = 0; #950000; //0.95ms
end
endmodule