FPGA初学-TLV1544

完全跟着老师的思路走的,该学的东西我都放在代码的注释里了

首先创建TLV1544_CTRL.v文件

module TLV1544_CTRL(

	Clk,
	Rst_n,
	
	Do_Conv,	//开始转换使能信号
	AD_DONE,	//转换完成信号//外部控制逻辑,也就是说外部什么时候控制adc开始转换呢,就是用这一个转换完成标志来实现
	ADC_CHSEL,	//通道选择
	
	ADC_DATA,	//采样结果
	DATA_Valid,
	
	TLV1544_SDO,//这个应该是数据吧	这个对于TLV1544来说是数据输出,而对于FPGA来说是数据输入
	TLV1544_SDI,	//这个是控制A1A2A3A0的,具体什么作用我也不懂
	TLV1544_SCLK,//数据接口时钟	
	TLV1544_NCS,	//芯片选择脚,该引脚由高变低会使器件内部的计数器和控制逻辑复位,并使能DATA IN,DATA OUT,和IO CLK,该引脚由低变高会禁止DATA IN,DATA OUT,和IO CLK的功能
	TLV1544_FS,//DSP的帧同步输入,FS信号指示了串行数据帧从器件中开始输入或输出。当使用微处理器接口时,该引脚连接到VCC
	TLV1544_EOC//转换忙标志位,当该引脚在IO CLK的第十个时钟的上升沿(微处理器模式)或下降沿(DSP 模式)变为低电平,并将保持低电平直到转换完成,数据已经就绪
);

	input Clk;
	input Rst_n;
	input Do_Conv;	//开始转换使能信号

	input [3:0]ADC_CHSEL;	//通道选择A0A1A2A3
	
	output reg [9:0]ADC_DATA;	//采样结果
	output reg AD_DONE;	//转换完成信号
	output reg DATA_Valid;
	
	input TLV1544_SDO;
	input TLV1544_EOC;//转换完成的标志信号
	output reg TLV1544_SDI;	
	output reg TLV1544_SCLK;	
	output reg TLV1544_NCS;
	output wire TLV1544_FS;
	
	assign TLV1544_FS = 1'b1;//整个过程中FS保持高电平不变
	
	reg [7:0] LSM_CNT;//序列计数器
	reg [9:0] rADC_DATA;//内部数据计数器,在整个转换的过程中,数据集都是往radc_DATA里面聚集,当转换完成之后,数据再送到我们的adc_DATA
	
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)
		LSM_CNT <= 8'd0;
	else if(LSM_CNT <204 && (TLV1544_EOC == 1'b1) && (Do_Conv || LSM_CNT > 8'd0))
		LSM_CNT <= LSM_CNT + 1'b1;
	else if(LSM_CNT < 204 && (TLV1544_EOC == 1'b0))
		LSM_CNT <= LSM_CNT;
	else if(LSM_CNT == 204 && (TLV1544_EOC == 1'b1))
		LSM_CNT <= 8'd0;
		
		
		//&是按位与
		//&&表示的是逻辑与
		//比如
		//a=4'b1001
		//b=4'b1100
		//a&b=4'b1000
		
		
	always@(posedge Clk or negedge Rst_n)
	if(!Rst_n)begin
		rADC_DATA <= 10'd0;
		TLV1544_SDI <= 1'b0;	
		TLV1544_SCLK <= 1'b0;	
		TLV1544_NCS <= 1'b1;	
		AD_DONE <= 1'b0;//转换完成信号
		DATA_Valid <= 1'b0;
		ADC_DATA <= 10'd0;
	end
	else begin
		case(LSM_CNT)
			0:
				begin
					rADC_DATA <= 10'd0;
					TLV1544_SDI <= 1'b0;	
					TLV1544_SCLK <= 1'b0;	
					TLV1544_NCS <= 1'b1;	
					AD_DONE <= 1'b0;
				end
				
			1:
				begin
					TLV1544_NCS <= 1'b0;	
					TLV1544_SDI <= ADC_CHSEL[3];	
				end
				
			9:
				begin
					TLV1544_SCLK <= 1'b1;
					rADC_DATA[9] <= TLV1544_SDO;
				end
				
			19:
				begin
					TLV1544_SDI <= ADC_CHSEL[2];
					TLV1544_SCLK <= 1'b0;			
				end
			
			29:
				begin
					TLV1544_SCLK <= 1'b1;
					rADC_DATA[8] <= TLV1544_SDO;
				end
				
			39:
				begin
					TLV1544_SDI <= ADC_CHSEL[1];
					TLV1544_SCLK <= 1'b0;			
				end
				
			49:
				begin
					TLV1544_SCLK <= 1'b1;
					rADC_DATA[7] <= TLV1544_SDO;
				end
				
			59:
				begin
					TLV1544_SDI <= ADC_CHSEL[0];
					TLV1544_SCLK <= 1'b0;			
				end
				
			69:
				begin
					TLV1544_SCLK <= 1'b1;
					rADC_DATA[6] <= TLV1544_SDO;
				end
				
			79:TLV1544_SCLK <= 1'b0;
			
			89:
				begin
					TLV1544_SCLK <= 1'b1;
					rADC_DATA[5] <= TLV1544_SDO;
				end
			99:TLV1544_SCLK <= 1'b0;
			
			109:
				begin
					TLV1544_SCLK <= 1'b1;
					rADC_DATA[4] <= TLV1544_SDO;
				end
				
			119:TLV1544_SCLK <= 1'b0;
			
			129:
				begin
					TLV1544_SCLK <= 1'b1;
					rADC_DATA[3] <= TLV1544_SDO;
				end
				
		   139:TLV1544_SCLK <= 1'b0;
			
		   149:
				begin
					TLV1544_SCLK <= 1'b1;
					rADC_DATA[2] <= TLV1544_SDO;
				end
				
			159:TLV1544_SCLK <= 1'b0;
			
			169:
				begin
					TLV1544_SCLK <= 1'b1;
					rADC_DATA[1] <= TLV1544_SDO;
				end
				
		   179:TLV1544_SCLK <= 1'b0;
			
	      189:
				begin
					TLV1544_SCLK <= 1'b1;
					//rADC_DATA[0] <= TLV1544_SDO;//这个时候是把sdo送到radC_DATA【0】里面,但它和下面整体赋值给adc_DATA是非阻塞的,也就是说同时进行的
					//所以我们可以把radC_DATA【91】和此时的sdo直接一起并值给adc_DATA
					if(TLV1544_EOC)
						DATA_Valid <= 1'b1;
					else
						DATA_Valid <= 1'b0;
					ADC_DATA <= {rADC_DATA[9:1],TLV1544_SDO};
				end
				
	      199:
				begin
					TLV1544_SCLK <= 1'b0;
					TLV1544_NCS <= 1'b1;
				end
				
			204:AD_DONE <= 1'b1;
			
			default:DATA_Valid <= 1'b0;
		endcase
	end

endmodule

然后编写test bench看看结果

`timescale 1ns/1ns

`define clk_period 20

module TLV1544_CTRL_tb;

	reg Clk;
	reg Rst_n;
	reg Do_Conv;	//开始转换使能信号

	reg [3:0]ADC_CHSEL;	//通道选择
	
	wire[9:0]ADC_DATA;	//采样结果
	wire AD_DONE;	//转换完成信号
	wire DATA_Valid;
	
	reg TLV1544_SDO;
	reg TLV1544_EOC;
	wire TLV1544_SDI;	
	wire TLV1544_SCLK;	
	wire TLV1544_NCS;
	wire TLV1544_FS;

	TLV1544_CTRL TLV1544_CTRL0(

		.Clk(Clk),
		.Rst_n(Rst_n),
		
		.Do_Conv(Do_Conv),	//开始转换使能信号
		.AD_DONE(AD_DONE),	//转换完成信号
		.ADC_CHSEL(ADC_CHSEL),	//通道选择
		
		.ADC_DATA(ADC_DATA),	//采样结果
		.DATA_Valid(DATA_Valid),
		
		.TLV1544_SDO(TLV1544_SDO),	
		.TLV1544_SDI(TLV1544_SDI),	
		.TLV1544_SCLK(TLV1544_SCLK),	
		.TLV1544_NCS(TLV1544_NCS),	
		.TLV1544_FS(TLV1544_FS),
		.TLV1544_EOC(TLV1544_EOC)
	);
	
	initial Clk = 1'b1;
	always #(`clk_period/2)Clk = ~Clk;
	
	initial begin
		Rst_n = 1'b0;
		Do_Conv = 1'b0;
		ADC_CHSEL = 4'b0;
		TLV1544_SDO = 1'b0;
		TLV1544_EOC = 1'b1;
		#(`clk_period * 10 +1);//主要是为了让rst_n的释放和我们的clk错开,便于观察信号的变化
		Rst_n = 1'b1;
		#(`clk_period * 10);
		ADC_CHSEL = 0;//选择通道0
		Do_Conv = 1'b1;//产生读使能信号
		#(`clk_period);
		Do_Conv = 1'b0;
		@(posedge (TLV1544_CTRL0.LSM_CNT == 8'd189))//在第十个模块时钟的上升沿的时候,模拟EOC等于0,也就是说数据转换完成了
		TLV1544_EOC = 1'b0;
		#(`clk_period*10 +3);
		TLV1544_EOC = 1'b1;
		#(`clk_period*1000 );
		
		ADC_CHSEL = 1;
		Do_Conv = 1'b1;
		#(`clk_period);
		Do_Conv = 1'b0;
		@(posedge (TLV1544_CTRL0.LSM_CNT == 8'd189))
		#(`clk_period);
		TLV1544_EOC = 1'b0;
		#(`clk_period*10 +3);
		TLV1544_EOC = 1'b1;
		#(`clk_period*1000 );
		$stop;
	end
	
	initial begin
	forever begin//forever必须在initial块中使用,不能在always块中使用
			TLV1544_SDO = ~TLV1544_SDO;
			#350;		
		end	
	end
	
endmodule

看是看完了,就是自己不会写,打算自己咸鱼几天看看别人的代码,如果弄懂了会自己试着写一个ad9226双通道采集代码。

本咸鱼需要采集六个大概1MHz左右的电压信号,有没有大佬试过这么高频率的多通道采样呀,求交流

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值