做一个2ASK试验 之一

 2ASK调试模式比较简单,就是用有信号和没有信号来表示0,1。现在问题就是如何从基带层面判断一个信号是有还是没有。当然是通过幅度。我们做一个模块算出波谷的绝对值,和波峰相加就得到了幅度。之后设置两个阈值,大于这个阈值1就认为是数值1,小于阈值0就认为是数值0,而在0,1之间的就保持之前的数值状态。

module amp_cal(
input clk ,
input [11:0] adc_value ,
output reg [12:0]  result,
output reg valid 
);

reg [11:0] trough,hill ,adc_value_r;
reg [11:0] abs_value ,abs_flag;
// stage 1
always @ (posedge clk )adc_value_r<=adc_value;

//stage 2 
always @ (posedge clk) if (adc_value_r[11]) abs_value <=    ~adc_value_r + 1 ; else abs_value <=    adc_value_r  ; 
always @ (posedge clk) abs_flag <= adc_value_r[11] ;

//stage 3
reg abs_flagr ;
always @ (posedge clk)  abs_flagr <= abs_flag ;wire fall_cross_zero = {abs_flagr,abs_flag} ==2'b01;
always @ (posedge clk)if (fall_cross_zero) trough<=0; else  if (abs_flag) if (trough < abs_value) trough <= abs_value;
always @ (posedge clk)if (fall_cross_zero) hill<=0; else  if (~abs_flag) if (hill < abs_value) hill <= abs_value;

//stage 4 
always @(posedge clk) if (fall_cross_zero) result <= trough + hill ;
always @(posedge clk) valid <= fall_cross_zero;

endmodule 

代码按照流水线方式写的,为了更好理解代码,看下面这个图:

 

波峰hill,波谷trough,从波峰降低到波谷穿越0点时候我们叫做fall_cross_zero。我fall_cross_zero时候我们看到hill和trough都已经算出来好了(都是正数,其中trough是波谷的绝对值),我们在fall_cross_zero是计算出来hill+trough就得到这这个周期的振幅。同时在fall_cross_zero时候清零波峰和波谷最大值保存器。

这里用流水线形式来写出发点不是为了考虑速度,而是有些运算为了让编译器搞明白(或者说为了让我们说明白,而不至于让编译器优化掉)多加寄存器的写法还是很可取的。

 

这个应该没有必要仿真的,想出错都难。

我们这里认为振幅超过一定的限度就是收到为了信号。但是这里存在一个问题,如下图表示:

 

在这例子里面,始终没有穿越0点,这样也就时钟算不出来一个result 。所以这时候我们应该再加上一个超时计数器,类似看门狗吧。当超过一定时间没有valid产生,他就产生一个复位信号清除result 输出0.这个超时的数值我们希望能可以设置,于是代码可以这样改写:

 


/*
  amp_cal_with_dog  amp_cal_with_dog (  
  .clk( ),
  .adc_value( ) ,   
  .result( ),  
  .valid( ) , 
  .time_of_value( ) 
);

*/


module amp_cal_with_dog (input clk ,
input [11:0] adc_value ,
output reg [12:0]  result,
output reg valid ,
input [15:0]time_of_value 
);

wire  [15:0] time_out_value_r  ;
synchronizer #(.WIDTH (  1  )) syn_time_of_value (  .clk(clk),    .in(time_of_value),  .out(time_of_value_r));
reg [15:0] cnt;
reg [11:0] trough,hill ,adc_value_r;
reg [11:0] abs_value ,abs_flag;

//stage 1
always @ (posedge clk )adc_value_r<=adc_value;

//stage 2 
always @ (posedge clk) if (adc_value_r[11]) abs_value <=    ~adc_value_r + 1 ; else abs_value <=    adc_value_r  ; 
always @ (posedge clk) abs_flag <= adc_value_r[11] ;

//stage 3
reg abs_flagr ;
always @ (posedge clk)  abs_flagr <= abs_flag ;wire fall_cross_zero = {abs_flagr,abs_flag} ==2'b01;
always @ (posedge clk)if (fall_cross_zero) trough<=0; else  if (abs_flag) if (trough < abs_value) trough <= abs_value;
always @ (posedge clk)if (fall_cross_zero) hill<=0; else  if (~abs_flag) if (hill < abs_value) hill <= abs_value;

//stage 4 
wire cnt_overflow = cnt == time_of_value_r ;
always @(posedge clk) if (fall_cross_zero | cnt_overflow )cnt<=0;else cnt<=cnt+1;
always @(posedge clk) if ( cnt_overflow) result<=0;else if (fall_cross_zero) result <= trough + hill ;
always @(posedge clk) valid <= fall_cross_zero | cnt_overflow ;

endmodule 

 

至于这个time_of_value如何设置呢,我认为设置1.5倍的周期就可以了。比方DDS出一个完整的波形用的点数是36,我们可以设置time_of_value为54 就可以。这里注意of是overflow的简写。

 

OK这个模块写好了,再继续琢磨下要做什么。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值