在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 1282|回复: 8

[求助] 求助这个ad采样的代码如何编写测试文件

[复制链接]
发表于 2019-5-21 16:32:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x

`define AD_CLK_TIME                        10'd49        //1.1M, 909ns,909 / (1 / 50M) = 45 =0x2D
`define AD_CLK_TIME_HALF        10'd24        //909ns / 2 = 454.5ns 45 / 2 = 22       

module Ad_Module
(       
        //Input
        CLK_50M,RST_N,
        //Output
        AD_CS,AD_CLK,AD_DATA,data_out
);
       
//---------------------------------------------------------------------------
//--        外部端口声明
//---------------------------------------------------------------------------
input                                        CLK_50M;                                //时钟的端口,开发板用的50M晶振
input                                        RST_N;                                //复位的端口,低电平复位
input                                        AD_DATA;                                //AD数据端口
output                                AD_CS;                                //AD片选端口
output                                AD_CLK;                                //AD时钟端口,最大不超过1.1MHz
output        [ 7:0]        data_out;                        //AD模数转换完成的数据输出


//---------------------------------------------------------------------------
//--        内部端口声明
//---------------------------------------------------------------------------
reg                                        AD_CS;                                //AD片选信号端口
reg                                        AD_CS_N;                                //AD_CS的下一个状态
reg                                        AD_CLK;                                //AD时钟,最大不超过1.1MHz
reg                                        AD_CLK_N;                        //AD_CLK的下一个状态

reg                [ 2:0]        ad_fsm_cs;                        //状态机的当前状态
reg                [ 2:0]        ad_fsm_ns;                        //状态机的下一个状态

reg                [ 5:0]        time_cnt;                        //用于记录一个时钟所用时间的定时器
reg                [ 5:0]        time_cnt_n;                        //time_cnt的下一个状态
reg                [ 5:0]        bit_cnt;                                //用来记录时钟周期个数的计数器
reg                [ 5:0]        bit_cnt_n;                        //bit_cnt的下一个状态

reg                [ 7:0]        data_out;                        //用来保存稳定的AD数据
reg                [ 7:0]        data_out_n;                        //data_out的下一个状态
reg                [ 7:0]        ad_data_reg;                //用于保存数据的移位寄存器
reg                [ 7:0]        ad_data_reg_n;                //ad_data_reg_n的下一个状态

parameter        FSM_IDLE                        = 3'h0;        //状态机的初始状态;
parameter        FSM_READY                = 3'h1;        //满足CS有效时的第一个1.4us的延时状态
parameter        FSM_DATA                        = 3'h2;        //读取8个数据状态
parameter        FSM_WAIT_CONV        = 3'h3;        //等待转换状态,等待17us;
parameter        FSM_END                        = 3'h4;        //结束的状态

//---------------------------------------------------------------------------
//--        逻辑功能实现       
//---------------------------------------------------------------------------
//时序电路,用来给ad_fsm_cs寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
        if(!RST_N)                                                                //判断复位
                ad_fsm_cs <= 1'b0;                                //初始化ad_fsm_cs值
        else
                ad_fsm_cs <= ad_fsm_ns;                        //用来给ad_fsm_ns赋值
end

//组合电路,用来实现状态机
always @ (*)
begin
        case(ad_fsm_cs)                                                //判断状态机的当前状态
                FSM_IDLE:
                                                                                                //3 x 0.909us = 2.727us用于初始化延时
                        if((bit_cnt == 6'd2 ) && (time_cnt == `AD_CLK_TIME))
                                ad_fsm_ns = FSM_READY;        //如果空闲状态完成就进入延时状态
                        else
                                ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变
                FSM_READY:
                                                                                                //2 x 0.909us = 1.818us用于延迟1.4us
                        if((bit_cnt == 6'd2 ) && (time_cnt == `AD_CLK_TIME))
                                ad_fsm_ns = FSM_DATA;        //如果延时状态完成就进入读取数据状态
                        else
                                ad_fsm_ns = ad_fsm_cs;  //否则保持原状态不变
                FSM_DATA:
                                                                                                //读取数据8位,1~8个时钟脉冲
                        if((bit_cnt == 6'd8 ) && (time_cnt == `AD_CLK_TIME))
                                ad_fsm_ns = FSM_WAIT_CONV;//如果读取数据状态完成就进入等待状态
                        else
                                ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变               
                FSM_WAIT_CONV:
                                                                                                //19 x 0.909us = 17.271us用于延迟17us
                        if((bit_cnt == 6'd10) && (time_cnt == `AD_CLK_TIME))
                                ad_fsm_ns = FSM_END;                //如果等待状态完成就进入读取状态
                        else
                                ad_fsm_ns = ad_fsm_cs;        //否则保持原状态不变  
                FSM_END:                                                               
                        ad_fsm_ns = FSM_READY;                //完成一次数据转换,进入下一次转换
                default:ad_fsm_ns = FSM_IDLE;                               
        endcase
end

//时序电路,用来给time_cnt寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
        if(!RST_N)                                                                //判断复位
                time_cnt <= 6'h0;                                        //初始化time_cnt值
        else
                time_cnt <= time_cnt_n;                        //用来给time_cnt赋值
end

//组合电路,实现0.909us的定时计数器
always @ (*)
begin
        if(time_cnt == `AD_CLK_TIME)                //判断0.909us时间
                time_cnt_n = 6'h0;                                //如果到达0.909us,定时器清零
        else
                time_cnt_n = time_cnt + 6'h1;        //如果未到0.909us,定时器继续加1
end

//时序电路,用来给bit_cnt寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
        if(!RST_N)                                                                //判断复位
                bit_cnt <= 6'h0;                                        //初始化bit_cnt值
        else
                bit_cnt <= bit_cnt_n;                        //用来给bit_cnt赋值
end

//组合电路,用来记录时钟周期个数的计数器
always @ (*)
begin
        if(ad_fsm_cs != ad_fsm_ns)                        //判断状态机的当前状态
                bit_cnt_n = 6'h0;                                        //如果当前的状态不等于下一个状态,计时器就清零
        else if(time_cnt == `AD_CLK_TIME_HALF)//判断0.4545us时间
                bit_cnt_n = bit_cnt + 6'h1;        //如果到达0.4545us,计数器就加1
        else
                bit_cnt_n = bit_cnt;                                //否则计数器保持不变
end

//时序电路,用来给AD_CLK寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
        if(!RST_N)                                                                //判断复位
                AD_CLK <= 1'h0;                                        //初始化AD_CLK值
        else
                AD_CLK <= AD_CLK_N;                                //用来给AD_CLK赋值
end

//组合电路,用来生成AD的时钟波形
always @ (*)
begin
        if(ad_fsm_cs != FSM_DATA)                        //判断状态机的当前状态
                AD_CLK_N = 1'h0;                                        //如果当前的状态不等于读取数据状态,AD_CLK_N就置0
        else if(time_cnt == `AD_CLK_TIME_HALF)//判断0.4545us时间
                AD_CLK_N = 1'h1;                                        //如果到达0.4545us,ADC_CLK_N就置1
        else if(time_cnt == `AD_CLK_TIME)//判断0.909us时间
                AD_CLK_N = 1'h0;                                        //如果到达0.909us,AD_CLK_N就置0
        else
                AD_CLK_N = AD_CLK;                                //否则保持不变
end

//时序电路,用来给AD_CS寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
        if(!RST_N)                                                                //判断复位
                AD_CS <= 1'h0;                                                //初始化AD_CS值
        else
                AD_CS <= AD_CS_N;                                        //用来给AD_CS赋值
end

//组合电路,用来生成AD的片选波形
always @ (*)
begin
        if((ad_fsm_cs == FSM_DATA) || (ad_fsm_cs == FSM_READY))//判断状态机的当前状态
                AD_CS_N = 1'h0;//如果当前的状态等于读取数据状态或等于延时1.4us状态,AD_CS_N就置0
        else
                AD_CS_N = 1'h1;//如果当前的状态不等于读取数据状态或不等于延时1.4us状态,AD_CS_N就置1
end

//时序电路,用来给ad_data_reg寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
        if(!RST_N)                                                                //判断复位
                ad_data_reg <= 8'h0;                                //初始化ad_data_reg值
        else
                ad_data_reg <= ad_data_reg_n;        //用来给ad_data_reg赋值
end

//组合电路,将AD线上的数据保存到移位寄存器中
always @(*)
begin
        if((ad_fsm_cs == FSM_DATA) && (!AD_CLK) && (AD_CLK_N))//判断每一个时钟的上升沿
                ad_data_reg_n = {ad_data_reg[6:0],AD_DATA};//将数据存入移位寄存器中,高位优先
        else
                ad_data_reg_n = ad_data_reg;        //否则保持不变
end

//时序电路,用来给data_out寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
        if(!RST_N)                                                                //判断复位
                data_out <= 8'h0;                                        //初始化data_out值
        else
                data_out <= data_out_n;                        //用来给data_out赋值
end

//组合电路,将移位寄存器中的数据存入data_out中,可用于输出
always @ (*)
begin
        if(ad_fsm_cs == FSM_END)                        //判断复位
                data_out_n = ad_data_reg;                //初始化data_out值
        else
                data_out_n = data_out;                        //用来给data_out赋值
end

endmodule


发表于 2019-5-21 17:29:29 | 显示全部楼层
功能feature:需要验证什么 。
验证策略:?
覆盖方法:?
输入:?
输出:?
 楼主| 发表于 2019-5-22 09:43:29 | 显示全部楼层
说的好高深 ,把我搞蒙了.我这就是箱变写关于这代码的测试文件.输入的模拟信号,输出数字信号.我就是有点看不懂.我就是啥都不懂.所以才问的
发表于 2019-5-22 15:46:07 | 显示全部楼层
直接用纯verilog写testbench吗?不需要考虑随机和功能完备性吗?就是输入一个满足时序的数据流,然后看结果?你什么都不懂,那你总要明白进去什么样的数,出来什么样的结果吧?否则你把代码发在这里,谁会给你分析呢?
发表于 2019-5-22 18:57:34 | 显示全部楼层


gaurson 发表于 2019-5-22 15:46
直接用纯verilog写testbench吗?不需要考虑随机和功能完备性吗?就是输入一个满足时序的数据流,然后看结果 ...


他这个应该是fpga设计,外部连接的是一个AD芯片,这种仿真不了吧,除非有AD芯片的仿真模型,是这样吗
发表于 2019-5-22 21:46:06 | 显示全部楼层
很不错  
 楼主| 发表于 2019-5-23 11:24:50 | 显示全部楼层
这个代码我都没看懂,工作原理我都没搞懂呢
发出来就是求教大家的
发表于 2019-5-23 15:50:36 | 显示全部楼层


lalala. 发表于 2019-5-22 18:57
他这个应该是fpga设计,外部连接的是一个AD芯片,这种仿真不了吧,除非有AD芯片的仿真模型,是这样吗
...


不用,基于这个代码就已经是数字部分的了。AD_DATA看到的就是0-1比特,只不过是什么格式的数据流,就需要楼主去了解了。
 楼主| 发表于 2019-5-23 16:20:41 | 显示全部楼层
好的,谢谢大家了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-9-22 11:29 , Processed in 0.019354 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表