OpenCores
URL https://opencores.org/ocsvn/openmsp430/openmsp430/trunk

Subversion Repositories openmsp430

[/] [openmsp430/] [trunk/] [fpga/] [altera_de0_nano_soc/] [doc/] [Terasic/] [DE0_NANO_SOC/] [Demonstrations/] [FPGA/] [DE0_NANO_SOC_ADC/] [DE0_NANO_SOC_QSYS/] [synthesis/] [submodules/] [adc_ltc2308.v] - Rev 221

Compare with Previous | Blame | View Log

module adc_ltc2308(
	clk, // max 40mhz
 
	// start measure
	measure_start, // posedge triggle
	measure_ch,
	measure_done,
	measure_dataread,
 
	// adc interface
	ADC_CONVST,
	ADC_SCK,
	ADC_SDI,
	ADC_SDO 
);
 
input								clk;
 
// start measure
input								measure_start;
input		[2:0]					measure_ch;
output	reg					measure_done;
output	[11:0]				measure_dataread;
 
 
 
output		          		ADC_CONVST;
output		          		ADC_SCK;
output	reg          		ADC_SDI;
input 		          		ADC_SDO;
 
 
/////////////////////////////////
// Timing definition 
 
// using 40MHz clock
// to acheive fsample = 500KHz
// ntcyc = 2us / 25ns  = 80
 
 
 
`define DATA_BITS_NUM		12
`define CMD_BITS_NUM			6
`define CH_NUM					8
 
`define tWHCONV            3   // CONVST High Time, min 20 ns
`define tCONV     			64 //52  // tCONV: type 1.3 us, MAX 1.6 us, 1600/25(assumed clk is 40mhz)=64  -> 1.3us/25ns = 52
                              // set 64 for suite for 1.6 us max
//                         +12 //data
 
`define tHCONVST           320 // 12  // here set 320( fsample = 100KHz) for if ADC input impedance is high, see below  
                                // If the source impedance of the driving circuit is low, the ADC inputs can be driven directly.
                                //Otherwise, more acquisition time should be allowed for a source with higher impedance.
 
										  // for acheiving 500KHz  fmax. set n cyc = 80.
`define tCONVST_HIGH_START	0 	
`define tCONVST_HIGH_END  	(`tCONVST_HIGH_START+`tWHCONV) 
 
`define tCONFIG_START		(`tCONVST_HIGH_END) 	
`define tCONFIG_END  		(`tCLK_START+`CMD_BITS_NUM - 1) 	
 
`define tCLK_START 			(`tCONVST_HIGH_START+`tCONV)
`define tCLK_END 	   		(`tCLK_START+`DATA_BITS_NUM)
 
`define tDONE 	   			(`tCLK_END+`tHCONVST)
 
// create triggle message: reset_n
reg pre_measure_start;
always @ (posedge clk)	
begin
	pre_measure_start <= measure_start;
end
 
wire reset_n;
assign reset_n = (~pre_measure_start & measure_start)?1'b0:1'b1;
 
// tick
reg [15:0] tick;	
always @ (posedge clk or negedge reset_n)	
begin
	if (~reset_n)
		tick <= 0;
	else if (tick < `tDONE)
		tick <= tick + 1;
end
 
 
/////////////////////////////////
// ADC_CONVST 
assign ADC_CONVST = (tick >= `tCONVST_HIGH_START && tick < `tCONVST_HIGH_END)?1'b1:1'b0;
 
/////////////////////////////////
// ADC_SCK 
 
reg clk_enable; // must sync to clk in clk low
always @ (negedge clk or negedge reset_n)	 
begin
	if (~reset_n)
		clk_enable <= 1'b0;
	else if ((tick >= `tCLK_START && tick < `tCLK_END))
		clk_enable <= 1'b1;
	else
		clk_enable <= 1'b0;
end
 
assign ADC_SCK = clk_enable?clk:1'b0;
 
 
///////////////////////////////
// read data
reg [(`DATA_BITS_NUM-1):0] read_data;
reg [3:0] write_pos;
 
 
 
assign measure_dataread = read_data;
 
always @ (negedge clk or negedge reset_n)	
begin
	if (~reset_n)
	begin
		read_data <= 0;
		write_pos <= `DATA_BITS_NUM-1;
	end
	else if (clk_enable)
	begin
		read_data[write_pos] <= ADC_SDO;
		write_pos <= write_pos - 1;
	end
end
 
///////////////////////////////
// measure done
wire read_ch_done;
 
assign read_ch_done = (tick == `tDONE)?1'b1:1'b0;
 
always @ (posedge clk or negedge reset_n)	
begin
	if (~reset_n)
		measure_done <= 1'b0;
	else if (read_ch_done)
		measure_done <= 1'b1;
end
 
///////////////////////////////
// adc channel config
 
// pre-build config command
reg [(`CMD_BITS_NUM-1):0] config_cmd;
 
 
`define UNI_MODE		1'b1   //1: Unipolar, 0:Bipolar
`define SLP_MODE		1'b0   //1: enable sleep
 
always @(negedge reset_n)
begin
	if (~reset_n)
	begin
		case (measure_ch)
			0 : config_cmd <= {4'h8, `UNI_MODE, `SLP_MODE}; 
			1 : config_cmd <= {4'hC, `UNI_MODE, `SLP_MODE}; 
			2 : config_cmd <= {4'h9, `UNI_MODE, `SLP_MODE}; 
			3 : config_cmd <= {4'hD, `UNI_MODE, `SLP_MODE}; 
			4 : config_cmd <= {4'hA, `UNI_MODE, `SLP_MODE}; 
			5 : config_cmd <= {4'hE, `UNI_MODE, `SLP_MODE}; 
			6 : config_cmd <= {4'hB, `UNI_MODE, `SLP_MODE}; 
			7 : config_cmd <= {4'hF, `UNI_MODE, `SLP_MODE}; 
			default : config_cmd <= {4'hF, 2'b00}; 
		endcase
	end
end
 
// serial config command to adc chip
wire config_init;
wire config_enable;
wire config_done;
reg [2:0] sdi_index;
 
assign config_init = (tick == `tCONFIG_START)?1'b1:1'b0;	
assign config_enable = (tick > `tCLK_START && tick <= `tCONFIG_END)?1'b1:1'b0;	// > because this is negative edge triggle
assign config_done = (tick > `tCONFIG_END)?1'b1:1'b0;	
always @(negedge clk)	
begin
	if (config_init)
	begin
		ADC_SDI <= config_cmd[`CMD_BITS_NUM-1];
		sdi_index <= `CMD_BITS_NUM-2;
	end
	else if (config_enable)
	begin
		ADC_SDI <= config_cmd[sdi_index];
		sdi_index <= sdi_index - 1;
	end
	else if (config_done)
		ADC_SDI <= 1'b0; //
end
 
 
 
 
endmodule
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.