|
2#

楼主 |
发表于 2015-8-4 09:21:55
|
只看该作者
本帖最后由 BOB_Sun 于 2015-8-4 10:07 编辑
1.3 边沿检测电路
时钟clk上升沿要锁存延时链输出中的0-1或1-0跳变,这种在时钟边沿处的跳变必定会违反触发器的时序约束关系,导致触发器的输出处于亚稳态状态,例如:“000011111”锁存后会出现“000101111”、“000010011”等情况,通过公式的上升沿检测电路可以抑制三位突变的情况并正确识别上升沿输出”000010000”。
其中r为边沿检测电路输出;d为锁存器输出;m为r与d的总位数;k表示第几位。
源程序:
module ris_g (
input [199:0] d,
output reg [199:0] r);
integer k;
always @(d)
begin
r[0] <= ~d[0] & d[1];
r[1] <= ~d[0] & ~d[1] & d[2];
for(k=2;k<199;k=k+1)
r[k] <= ~d[k-2] & ~d[k-1] & ~d[k] & d[k+1];
r[199] <= 1'b0;
end
endmodule
同理下降沿检测电路如公式所示。
源程序:
module fal_g (
input [199:0] d,
output reg [199:0] f);
integer k;
always @(d)
begin
f[0] <= d[0] & ~d[1];
f[1] <= d[0] & d[1] & ~d[2];
for(k=2;k<199;k=k+1)
f[k] <= d[k-2] & d[k-1] & d[k] & ~d[k+1];
f[199] <= 1'b0;
end
endmodule
1.4 编码器
边沿检测电路的输出最终为”…0001000…”的形式,1表示0-1或1-0跳变的位置。求出1的位置编号的方法主要MUX结构、Fat Tree结构、Wallace Tree结构和ROM结构,此处不对这些方法进行介绍和比较,从程序编写的难易程度、路径延时、资源使用上最终选择ROM结构的编码器。
其中rp为编码器输出;i为位置编号;m为编码器输入的位数;OR表示或运算。
源程序:
module encoder(
input [199:0] srin,
output [8:0] tenout
);
integer i,k,j;
reg cen_valid;
reg [8:0] cen_tenout;
reg [255:0] cen_srin;
always @(srin)
begin
cen_srin = {{58{1'b0}},srin[199:2]};
cen_tenout = {9{1'b0}};
for(i=0;i<8;i=i+1)
for(k=0;k<2**(7-i);k=k+1)
for(j=(2**i)*(2*k+1)-1;j<=(2**(i+1))*(k+1)-2;j=j+1)
cen_tenout = cen_srin[j] | cen_tenout;
end
assign tenout = cen_tenout;
endmodule
1.5总结
最终的顶层原理图:
图 12 系统顶层原理图
源程序:
module do_in (
din,
dataa,
data_a);
input din;
output [199:0] dataa,data_a;
assign dataa = {{199{1'b0}},din};
assign data_a = {200{1'b1}};
endmodule
module n_counter (
input clock,
input st1,
output reg [199:0] n);
always @(posedge clock )
begin
if(st1) n <= n + 1;
end
endmodule
module for_store (
input clk,
input [199:0] m_in,
input [8:0] f_in,
input [8:0] r_in,
output reg wr,
output reg [255:0] d_store);
always @(posedge clk)
begin
if(f_in && r_in ) begin d_store <= f_in - r_in; wr <= 1'b1; end
else begin
if(r_in) begin d_store <= (m_in << 9) + f_in - r_in; wr <= 1'b1; end
else wr <= 1'b0;
end
end
endmodule
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module d_fifo (
data,
rdclk,
rdreq,
wrclk,
wrreq,
q,
rdempty,
wrfull);
input [255:0] data;
input rdclk;
input rdreq;
input wrclk;
input wrreq;
output [255:0] q;
output rdempty;
output wrfull;
wire [255:0] sub_wire0;
wire sub_wire1;
wire sub_wire2;
wire [255:0] q = sub_wire0[255:0];
wire rdempty = sub_wire1;
wire wrfull = sub_wire2;
dcfifo dcfifo_component (
.data (data),
.rdclk (rdclk),
.rdreq (rdreq),
.wrclk (wrclk),
.wrreq (wrreq),
.q (sub_wire0),
.rdempty (sub_wire1),
.wrfull (sub_wire2),
.aclr (),
.rdfull (),
.rdusedw (),
.wrempty (),
.wrusedw ());
defparam
dcfifo_component.intended_device_family = "Cyclone V",
dcfifo_component.lpm_numwords = 256,
dcfifo_component.lpm_showahead = "OFF",
dcfifo_component.lpm_type = "dcfifo",
dcfifo_component.lpm_width = 256,
dcfifo_component.lpm_widthu = 8,
dcfifo_component.overflow_checking = "ON",
dcfifo_component.rdsync_delaypipe = 4,
dcfifo_component.underflow_checking = "ON",
dcfifo_component.use_eab = "ON",
dcfifo_component.wrsync_delaypipe = 4;
endmodule
系统的250MHz的时钟可以使用一个PLL生成,最终的输出结果,可以由Nios II或者ARM核进行读取按照公式进行计算得到结果,所以在时间数字转换器和CPU之间必须增加一个FIFO来实现异步时钟的读写。另外:
1. FIFO的长度和连续测量的次数有关,此处可以缩小至所期望的,不需要256个存储空间。
2. 最终的准确计算结果应该对tf和tr进行除以2修正,因为在芯片一个LABCELL中两个全加器只有一个延时值。
3. 从测量的角度来看,采用多通道测量最后求平均可以进一步提升测量精度。
(完)
|
|