在遥远的 Mars星上有一种类似地球萤火虫的生物 星上有一种类似地球萤火虫的生物 —— 外星萤火虫。
外星萤火虫是社群生物,“ 外星萤火虫是社群生物,“ 虫后 ”以自己的发光信息 ”以自己的发光信息 f0(正常时是 30%占 空比的 毫秒脉冲, 繁殖季为 占空比为 50%,年老时占空比逐渐减小 ,周期逐渐 增大, 直至死亡)控制整个 族群的活动。 虫后死亡如果没有新的及时出 现,族群成员就会四处逃散。
“信虫 ”负责信息中转、传达, 为了使虫后的指令能够到整个族”负责信息中转、传达, 为了使虫后的指令能够到整个族信虫看到后或者其它发光时会自动同步己的器,使得f1与虫后 的 f0同频相,并且自动调整发光 同频相,并且自动调整发光 脉冲宽度为 0.3毫秒, 以免虫族成 员发现虫后衰老而引起恐慌, 保障虫族安定。
“哨虫 ”在虫族领地边界戍卫 ,哨看到信的号会同步反馈一个防”在虫族领地边界戍卫 ,哨看到信的号会同步反馈一个防信号,如果安全 (sta= =0),防卫信号是一个与 f1同相的 双脉冲 双脉冲 信号 f2a(脉冲宽 度 0.1毫秒);当敌人来犯 (sta= =1),防卫信号是 ,防卫信号是 三脉冲 信号 f2b(脉冲宽度 0.1毫 秒)。
哨虫离开边界地区会自动变换职责为信虫。
本题是一个创新类的数电实验,将上升沿检测、脉冲产生等要求综合在一个“实际”的应用场景中。
时钟作为产生脉冲的基准,仅用来作为产生脉冲的其中一个触发信号,另外一个触发信号是虫后的上升沿,此处就涉及到两个上升沿的检测,首先排一下坑:同一个always语句不能同时检测两个posedge,会报错;如果用两个always语句同时检测,在FPGA中,几个always语句是同时执行的,这其中涉及几个变量之间的互相赋值,Quartus会报一个变量在同一时钟周期里给同一变量多次赋值的错。
在时钟clk的上升沿检测的条件下,增加手动的虫后上升沿检测。具体操作为:每个时钟将虫后的状态保存到缓存变量中,下一个时钟周期中,对虫后的现态和上一次状态进行判断,如果是上升沿,则产生脉冲信号。
脉冲信号的产生:脉冲信号的产生依赖于FPGA 中的50MHz高频时钟,只需要类似于分频的操作就行。
// 外星萤火虫设计
module xx_xxxx_6(clk,f0,f1,p,sta,f2);
input f0,clk,p,sta;
output reg f1,f2;
reg [14:0]cnt;
reg temp,flag;
always @(posedge clk)
begin
if(temp==1'b0&&f0==1'b1) flag<=1'b1; //判断f0上升沿,并给出标志信号
if(flag)
begin
casex({p,sta})
2'b0_x:begin //f1和f2均为信虫状态
if(cnt<15'd15000)begin f1<=1'b1;f2<=1'b1;cnt<=cnt+1'd1;end
else begin f1<=1'b0;f2=1'b0;cnt<=15'd0;flag<=1'b0;end //脉冲产生结束,标志信号置0
end
2'b1_0:begin //f2为哨虫且边界安全
if(cnt<15'd5000)begin f1<=1'b1;f2<=1'b1;cnt<=cnt+1'd1;end
else if(cnt<15'd10000) begin f1<=1'b1;f2<=1'b0;cnt<=cnt+1'd1;end
else if(cnt<15'd15000) begin f1<=1'b1;f2<=1'b1;cnt<=cnt+1'd1;end
else begin f1<=1'b0;f2=1'b0;cnt<=15'd0;flag<=1'b0;end
end
2'b1_1:begin //f2为哨虫且边界危险
if(cnt<15'd5000)begin f1<=1'b1;f2<=1'b1;cnt<=cnt+1'd1;end
else if(cnt<15'd10000) begin f1<=1'b1;f2<=1'b0;cnt<=cnt+1'd1;end
else if(cnt<15'd15000) begin f1<=1'b1;f2<=1'b1;cnt<=cnt+1'd1;end
else if(cnt<15'd20000) begin f1<=1'b0;f2<=1'b0;cnt<=cnt+1'd1;end
else if(cnt<15'd25000) begin f1<=1'b0;f2<=1'b1;cnt<=cnt+1'd1;end
else begin f1<=1'b0;f2=1'b0;cnt<=15'd0;flag<=1'b0;end
end
endcase
end
else cnt<=15'd0;
temp<=f0;
end
endmodule
下面是modelsim仿真代码
//test
`timescale 1ns/1ns
module tese_xx_xxxx_6;
//clk,f0,f1,p,sta,f2
wire f1,f2;
reg clk,f0,p,sta;
initial //初始化变量
begin
clk=0;
f0=0;
p=0;
sta=0;
#6000000 sta=1;
#4000000 p=1;
#4000000 sta=0;
#5000000 sta=1;
end
always #10 clk=~clk; //50MHz时钟信号
always
begin //产生凌乱的虫后信号
#100000 f0=1; //f0信号
#600000 f0=0;
#1000000 f0=1;
#1300000 f0=0;
#1800000 f0=1;
#1900000 f0=0;
end
xx_xxxx_6 test(.clk(clk),.f0(f0),.p(p),.sta(sta),.f1(f1),.f2(f2));
endmodule
仿真结果如图
变量从上到下依次为:clk、f0,p,sta,f1,f2。
点个赞,不定时更新~~