基础篇-verilog-单路串行ADC-TLC549
注明:虽然此实验来自于诸多入门教程,其中包括gao石的,但我个人觉得他的时序写的不好,没有完全遵循芯片的时序,它直接用AD——CLK的上升沿读取AD_DATA, 但是,事实上,芯片时序,并不是在8位全在上升沿读取。
8位串行模数转换器
8位开关电容逐次逼近的方法实现A/D
内部具有4MHz的系统时钟,转换速度小于17us
允许的最大转换速率是40000次/s(一个周期,采样下来,再读取。)
电源3V到6V
方便采用3线串行接口方式与各种微处理器进行连接
最高有效位(A7)在CS降低后自动置于数据输出总线上。剩下的7位(a6 - a0)在前7个I / O时钟的边缘上被锁定了。B7-B0遵循同样的方式。
根据NOTEs的意思,也就是DA_DATA遵循某种时序串行吐出data,那么,在何时才吐出的是DATA的哪一位呢?
这就要遵循一定的时序关系。
这种关系便是:
在第一个CLK的上升沿读取A7,第一个CLK到第六个CLK的下降沿读取A6——A0。
思路:状态机:3个状态
1:转换状态(也可视作初始状态)
2:1.4us(CS由高变低状态)
3:DA_CLK(采样状态)
//-----------------------------------------------------------------------------2018.11.6 23:00
//------------------------------------------------------------------------------- 明日再来写
系统时钟是4M,并非是采样时钟,注意采样在SAMPLE阶段,也就是后4个时钟周期进行的。外接时钟速率1.1M并不是指的采样速率,那是接口读取速率。串行芯片,我门需要注意的是一个周期,采样时间+转换时间=1/40_000 而在并行芯片中,往往是给的CLOCK即采样时钟。
下图是AD904芯片时序,在DATA_change阶段进行采样,并进行完成相关的量化。
下面的代码,串行TLC549,采样后,存储在8位寄存器当中
module AD_TLC549
#(parameter T_conv=12'd850,//转换时间50M*17us=850parameter T_su=8'd70,//准备时间50M*1.4us=70usparameter AD_CLK_nop=4'd8,//定义8个AD_CLKparameter AD_CLK_circle_time=6'd46,//0.92usparameter AD_CLK_circle_time_half=6'd23 //23*50=0.46us
)
(
input sys_clk,
input RST_N,
input AD_DATA,
//-------------------
output AD_CLK,
output CS_N,output reg [AD_CLK_nop-1:0] AD_out_DATA //串行的AD_DATA转并行的8位寄存器);wire AD_CLK_edg;
reg AD_out_reg_finish;//串行转并行完成标志
reg [11:0] T_conv_cnt=0;//转换时间的计数器
reg [7:0] T_su_cnt=0;//准备时间的计数器
reg [3:0] AD_CLK_cnt=0;//AD_CLK个数计数器
reg [5:0] AD_CLK_circle_time_cnt=0;//一个AD_CLK的高/低电平时间计数器
reg AD_CLK_reg_reg;//用于缓存一拍AD_CLK,实现下降沿检测//设置输出寄存器
reg AD_CLK_reg=0;
reg CS_N_reg;reg [AD_CLK_nop-1:0] AD_out_reg;//采用三段式状态机
/*有限状态机,三段式建模风格*/
/*三个过程*/
//状态编码
localparam transition_state = 3'b001,//数据转换状态ready_1_4_state = 3'b010,//准备采样状态Acess_sample_state = 3'b100;//采样状态
//这里可以把数据转换状态视作初始状态,1没有时钟,2 CS_N为高,也无效。
reg [2:0] now_state=transition_state;
reg [2:0] next_state=transition_state;//1.实现状态转换:实现当前状态now_state到next_state的转换
always @ (posedge sys_clk)
beginif(!RST_N)now_state<=transition_state;elsenow_state<=next_state;
end
//2.设置状态切换条件,产生下一个状态
always@(*)
begincase(now_state)transition_state:if(T_conv_cnt==T_conv) //如果转换时间36next_state=ready_1_4_state;elsenext_state=transition_state;ready_1_4_state:if(T_su_cnt==T_su)next_state=Acess_sample_state;elsenext_state=ready_1_4_state; Acess_sample_state:if(AD_CLK_cnt<AD_CLK_nop)next_state=Acess_sample_state;elsenext_state=transition_state; default:;endcaseend//3.产生每个状态机的条件输出值
always @ (posedge sys_clk)
begincase(next_state)transition_state:beginT_conv_cnt<=T_conv_cnt+1;T_su_cnt<=0;AD_CLK_cnt<=0;endready_1_4_state:beginT_su_cnt<=T_su_cnt+1;T_conv_cnt<=0;endAcess_sample_state:beginif (AD_CLK_edg)AD_CLK_cnt <= AD_CLK_cnt + 1'b1;elseAD_CLK_cnt <= AD_CLK_cnt;endendcaseend
//4.设置每个输出值
//1.CS_N的输出值
always@(posedge sys_clk)
beginif(!RST_N)beginCS_N_reg<=1; //end else if(now_state==transition_state)beginCS_N_reg<=1; //endelse beginCS_N_reg<=0; //CS_N低电平有效end
end
assign CS_N=CS_N_reg;//2.AD_CLK的输出值
always@(posedge sys_clk)
beginif(!RST_N)AD_CLK_circle_time_cnt<=0;else if(now_state==Acess_sample_state)AD_CLK_circle_time_cnt<=(AD_CLK_circle_time_cnt<AD_CLK_circle_time-1)?(AD_CLK_circle_time_cnt+1'b1):0;elseAD_CLK_circle_time_cnt<=0;
endalways@ (posedge sys_clk)
beginif(!RST_N)AD_CLK_reg<=0;else if(now_state==Acess_sample_state)AD_CLK_reg <= (AD_CLK_circle_time_cnt <=AD_CLK_circle_time_half-1) ? 1'b1 : 1'b0;elseAD_CLK_reg<=0;
end
//3.AD_CLK_nop_edg控制
always @ (posedge sys_clk)
beginAD_CLK_reg_reg<=AD_CLK_reg; //寄存一拍
endassign AD_CLK_edg = AD_CLK_reg_reg&(~AD_CLK_reg);//判断下降沿assign AD_CLK=AD_CLK_reg;//4.AD_DATA_reg控制读取........控制在什么时候,把串行AD_DATA的数据写入多位的寄存器AD_DATA_reg之中,时机不对,自然写入的数肯定就不对
always @ (posedge sys_clk)
beginif((now_state==ready_1_4_state)&(next_state==Acess_sample_state))AD_out_reg[AD_CLK_nop-1]<=AD_DATA;else if(AD_CLK_edg&(AD_CLK_cnt<=AD_CLK_nop-1))AD_out_reg[AD_CLK_nop-1-1:0]<={AD_out_reg[AD_CLK_nop-1-1-1:0],AD_DATA};//移位循环实现串行转并行else if(AD_CLK_cnt==AD_CLK_nop)//在第8个时钟下降沿的时候,代表了AD_DATA_reg已经移位完成,之所以没有刚好设置第7个下降沿,是担心第7个下降沿还在读取。AD_out_reg_finish<=1;elsebeginAD_out_reg<=AD_out_reg;AD_out_reg_finish<=0; endendalways @ (posedge sys_clk)
beginif(AD_out_reg_finish==1) //只有在读取8位完毕后,再将这8位数更新AD_out_DATA<=AD_out_reg;elseAD_out_DATA<=AD_out_DATA;
endendmodule
// Copyright (C) 1991-2013 Altera Corporation
// Your use of Altera Corporation's design tools, logic functions
// and other software and tools, and its AMPP partner logic
// functions, and any output files from any of the foregoing
// (including device programming or simulation files), and any
// associated documentation or information are expressly subject
// to the terms and conditions of the Altera Program License
// Subscription Agreement, Altera MegaCore Function License
// Agreement, or other applicable license agreement, including,
// without limitation, that your use is for the sole purpose of
// programming logic devices manufactured by Altera and sold by
// Altera or its authorized distributors. Please refer to the
// applicable agreement for further details.// *****************************************************************************
// This file contains a Verilog test bench template that is freely editable to
// suit user's needs .Comments are provided in each section to help the user
// fill out necessary details.
// *****************************************************************************
// Generated on "11/08/2018 16:19:41"// Verilog Test Bench template for design : AD_TLC549
//
// Simulation tool : ModelSim (Verilog)
// `timescale 1 ns/ 1 ps
module AD_TLC549_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg AD_DATA;
reg RST_N;
reg sys_clk;
// wires
wire AD_CLK;
wire [7:0] AD_out_DATA;
wire CS_N;// assign statements (if any)
AD_TLC549 i1 (
// port map - connection between master ports and signals/registers .AD_CLK(AD_CLK),.AD_DATA(AD_DATA),.AD_out_DATA(AD_out_DATA),.CS_N(CS_N),.RST_N(RST_N),.sys_clk(sys_clk)
);
initial
begin
$display("Running testbench");
#0 sys_clk=0;
#0 RST_N=0;
#40 RST_N=1;
#0 AD_DATA=1;end
//------------------------------------------
always
begin #10 sys_clk=~sys_clk; end
endmodule
在第8个AD_clk过后才更新AD_out_DATA
整体效果:
符合AD_CLK 一个周期0.92us,半个周期长度也符合,检查了
符合1.4us
以下是工程连接:
https://download.csdn.net/download/ciscomonkey/10773104
基础篇-verilog-单路串行ADC-TLC549相关推荐
- 硬件之路-串行LCD12864之MSP430简单实现
为什么80%的码农都做不了架构师?>>> 串行LCD12864引脚接法: 实现代码(MSP430): /** 12864.c* Created on: 2014-7-15* Auth ...
- C语言基础篇02:单链表实现学生成绩管理系统
单链表实现学生成绩管理系统 前言 需求分析 详细设计 增加成绩信息 删除成绩信息 修改成绩信息 查询学生信息和浏览学生信息 总结 前言 上篇已经讲过单链表的基本实现,这篇将以一个简单的管理系统入手. ...
- Vue2基础篇-21-非单文件组件
1. 基本使用 <!DOCTYPE html> <html><head><meta charset="UTF-8"><titl ...
- verilog并行数据转换为串行输出
代码实现在conv_en的控制下,将16位并行数据,转换为串行数据输出,并行数据转换为串行数据后,第一个周期是空的,第二个周期才会有数据输出,因为复位过后的din_reg初始值为0. module A ...
- FPGA数字信号处理(三)串行FIR滤波器Verilog设计
该篇是FPGA数字信号处理的第三篇,选题为DSP系统中极其常用的FIR滤波器.本文将在上一篇"FPGA数字信号处理(二)并行FIR滤波器Verilog设计" https://blo ...
- CRC-16/XMODEM串行计算的Verilog源码及仿真
文章目录 前言 一.CRC是什么? 二.硬件串行计算原理分析 1. 串行计算原理分析 (1) 原理图 (2) 计算过程 (3) 以CRC-16/XMODEM为例 2. Verilog代码 3. 仿真结 ...
- 最全MySQL基础篇
文章目录 导入表的问题 第三章_最基本的SELECT语句 1. SQL语言的规则和规范 1) 基本规则 2) SQL大小写规范(建议遵守) 3) 注释 4) 命名规则 2. 基本的SELECT语句 1 ...
- 串行、并行都是什么?为什么串行可以高速?
https://www.bilibili.com/read/cv355543 一说起接口,就不得不提到串行和并行,而且近几年主要看到的接口一般都是串行接口,似乎并行接口已经成为明日黄花.那么,串行和并 ...
- python视频教程推荐it教程网_Python视频教程之入门基础篇_IT教程网
资源名称:Python视频教程之入门基础篇 资源目录: [IT教程网]320b96cae58124db5fb6e7c5df99aefc [IT教程网]699434136852f34ec720f2a34 ...
最新文章
- gitee中同步github的repository提示:账户或密码错误
- 【渝粤教育】国家开放大学2018年春季 0699-22T阅读与写作 参考试题
- 编写一个猜数字游戏程序:
- Java工作笔记-Spring Boot中使用Mybatis操作达梦数据库
- Go 官方未来会不会支持循环引用?
- VMware vs openStack对比直观优势
- Bag-of-words模型
- JavaScript JSON 对象使用详解、JSON. parse()、JSON. stringify()
- python 修改图片_Python实现批量修改图片格式和大小的方法【opencv库与PIL库】
- c语言常见头文件大全,C语言头文件大全
- cdrx7拼版工具在哪里_CorelDRAW X7标签怎么排版?
- 数字图像处理(三)直方图规定化
- 算法第一次作业(2.帐篷问题)
- 在FTP服务器上搜索网页
- 如何将JSONArray转为String数组
- linux read() 函数
- App Clips 的配置及链接处理
- 自制的万年历收音机功能完工。
- zizhan - 瞄准镜
- 阿里开发的这个网站,让我写文章效率提高50%
热门文章
- linux centos 7安装 apache php 及mariadb
- 20150127--Session入库
- 甲骨文全球大会——看SOA
- ASP.NETSpring.NETNHibernate最佳实践(三)——第2章环境准备
- 控件属性、事件持久化
- 可以下载Microsoft ISA Server 2006 试用版了,网管需要关注
- UA OPTI570 量子力学8 每一个左矢都有与之对应的右矢吗?
- Dirichlet分布与多项分布的共轭性
- UA MATH567 高维统计专题1 稀疏信号及其恢复3 Coherence与RIP简介
- 图解在8086模拟器中运行汇编helloworld程序