2010-04-03 05:44:09 +03:00
|
|
|
`timescale 1ns / 1ps
|
2010-04-03 07:30:52 +03:00
|
|
|
module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART,
|
|
|
|
ADC_SCLK, ADC_SDIN, ADC_SDOUT,
|
|
|
|
addr, rdBus, wrBus, we);
|
2010-04-03 05:44:09 +03:00
|
|
|
|
2010-04-03 07:30:52 +03:00
|
|
|
input clk, reset, ADC_EOC, cs, we;
|
2010-04-04 21:58:41 +03:00
|
|
|
input [10:0] addr;
|
2010-04-03 07:30:52 +03:00
|
|
|
input [7:0] wrBus;
|
|
|
|
output ADC_CS, ADC_CSTART, ADC_SCLK;
|
|
|
|
output [7:0] rdBus;
|
2010-04-03 05:44:09 +03:00
|
|
|
inout ADC_SDIN, ADC_SDOUT;
|
|
|
|
|
2010-04-04 21:58:41 +03:00
|
|
|
//RAMB registers
|
|
|
|
reg [7:0] rdBus;
|
|
|
|
wire [7:0] rdBus1;
|
2010-04-03 07:30:52 +03:00
|
|
|
wire [7:0] rdBus2;
|
2010-04-03 05:44:09 +03:00
|
|
|
reg [7:0] wrBus2;
|
2010-04-04 21:58:41 +03:00
|
|
|
reg [10:0] addr2;
|
|
|
|
reg we1=0;
|
|
|
|
reg we2=0;
|
|
|
|
wire we;
|
|
|
|
|
|
|
|
//Control registers
|
|
|
|
reg nSample=0;
|
|
|
|
reg [10:0] auto_count=0;
|
2010-04-03 05:44:09 +03:00
|
|
|
reg [4:0] w_st2=0;
|
2010-04-04 21:58:41 +03:00
|
|
|
|
|
|
|
//SPI registers
|
2010-04-03 05:44:09 +03:00
|
|
|
reg [3:0] SPI_in_data=0;
|
|
|
|
reg [9:0] SPI_out_data;
|
|
|
|
reg SPI_rd = 0;
|
2010-04-04 21:58:41 +03:00
|
|
|
reg SPI_wr = 0;
|
2010-04-03 07:30:52 +03:00
|
|
|
|
2010-04-04 21:58:41 +03:00
|
|
|
// Confiuration registers
|
|
|
|
reg CMD_DONE;
|
|
|
|
reg CMD_TYP;
|
|
|
|
reg [3:0] CMD_ADC;
|
|
|
|
reg [7:0] CLKDIV = 0;
|
|
|
|
reg [10:0] SIZEB; //[10:8] -> size_hi | [7:0] -> size_low
|
|
|
|
//TEMPS
|
|
|
|
reg [10:0] SIZEB2;
|
|
|
|
reg CMD_DONE2;
|
|
|
|
|
2010-04-03 05:44:09 +03:00
|
|
|
assign ADC_CSTART = 1'b1;
|
|
|
|
|
2010-04-03 07:30:52 +03:00
|
|
|
// Dual-port RAM instatiation
|
|
|
|
RAMB16_S9_S9 ba0(
|
2010-04-04 21:58:41 +03:00
|
|
|
.DOA(rdBus1), // Port A 8-bit Data Output
|
2010-04-03 07:30:52 +03:00
|
|
|
.DOB(rdBus2), // Port B 8-bit Data Output
|
|
|
|
.DOPA(), // Port A 1-bit Parity Output
|
|
|
|
.DOPB(), // Port B 1-bit Parity Output
|
2010-04-04 21:58:41 +03:00
|
|
|
.ADDRA(addr[10:0]), // Port A 11-bit Address Input
|
|
|
|
.ADDRB(addr2[10:0]), // Port B 11-bit Address Input
|
2010-04-03 07:30:52 +03:00
|
|
|
.CLKA(~clk), // Port A Clock
|
|
|
|
.CLKB(~clk), // Port B Clock
|
|
|
|
.DIA(wrBus), // Port A 8-bit Data Input
|
|
|
|
.DIB(wrBus2), // Port B 8-bit Data Input
|
|
|
|
.DIPA(1'b0), // Port A 1-bit parity Input
|
|
|
|
.DIPB(1'b0), // Port-B 1-bit parity Input
|
|
|
|
.ENA(1'b1), // Port A RAM Enable Input
|
|
|
|
.ENB(1'b1), // Port B RAM Enable Input
|
|
|
|
.SSRA(1'b0), // Port A Synchronous Set/Reset Input
|
|
|
|
.SSRB(1'b0), // Port B Synchronous Set/Reset Input
|
|
|
|
.WEA(we1), // Port A Write Enable Input
|
|
|
|
.WEB(we2) ); // Port B Write Enable Input
|
|
|
|
|
2010-04-03 05:44:09 +03:00
|
|
|
// SPI comunication module instantiation
|
|
|
|
reg ADC_SCLK_buffer = 0;
|
|
|
|
reg ADC_SDIN_buffer = 0;
|
|
|
|
reg busy = 0;
|
|
|
|
|
|
|
|
reg [3:0] in_buffer=0;
|
|
|
|
reg [9:0] out_buffer;
|
|
|
|
reg [7:0] clkcount = 0;
|
|
|
|
reg [4:0] count = 0;
|
|
|
|
|
|
|
|
assign ADC_CS = ~busy;
|
|
|
|
|
2010-04-04 21:58:41 +03:00
|
|
|
always@(SPI_rd or out_buffer or busy or CLKDIV)
|
2010-04-03 05:44:09 +03:00
|
|
|
begin
|
|
|
|
SPI_out_data = 10'bx;
|
|
|
|
if(SPI_rd)
|
|
|
|
begin SPI_out_data = out_buffer; end
|
|
|
|
end
|
|
|
|
|
|
|
|
always@(negedge clk)
|
|
|
|
begin
|
|
|
|
if(!busy)
|
|
|
|
begin
|
|
|
|
if(SPI_wr)
|
|
|
|
begin in_buffer = SPI_in_data; busy = 1; end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
begin
|
|
|
|
clkcount = clkcount + 1;
|
2010-04-04 21:58:41 +03:00
|
|
|
if(clkcount >= CLKDIV)
|
2010-04-03 05:44:09 +03:00
|
|
|
begin
|
|
|
|
clkcount = 0;
|
|
|
|
// Send the ADC CMD on first 4 rising edge of SCLK
|
|
|
|
if((count % 2) == 0)
|
|
|
|
begin
|
|
|
|
ADC_SDIN_buffer = in_buffer[3];
|
|
|
|
in_buffer = in_buffer << 1;
|
|
|
|
end
|
|
|
|
// We generate 10 cicles of SCLK
|
|
|
|
if(count > 0 && count < 21)
|
|
|
|
begin
|
|
|
|
ADC_SCLK_buffer = ~ADC_SCLK_buffer;
|
|
|
|
end
|
|
|
|
count = count + 1;
|
|
|
|
if(count > 21)
|
|
|
|
begin
|
|
|
|
count = 0;
|
|
|
|
busy = 0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
always@(posedge ADC_SCLK_buffer)
|
|
|
|
begin
|
|
|
|
out_buffer = out_buffer << 1;
|
|
|
|
out_buffer[0] = ADC_SDOUT;
|
|
|
|
end
|
|
|
|
|
|
|
|
assign ADC_SCLK = ADC_SCLK_buffer;
|
|
|
|
assign ADC_SDIN = ADC_SDIN_buffer;
|
|
|
|
|
2010-04-04 21:58:41 +03:00
|
|
|
// Write control
|
|
|
|
always @(negedge clk)
|
|
|
|
if(reset)
|
|
|
|
{CMD_TYP,CMD_ADC,SIZEB,we1} <= 0;
|
|
|
|
else if(we & cs) begin
|
|
|
|
case (addr)
|
|
|
|
0: begin CMD_TYP <= wrBus[4];
|
|
|
|
CMD_ADC[3:0] <= wrBus[3:0]; end
|
|
|
|
1: begin CLKDIV <= wrBus; end
|
|
|
|
2: begin SIZEB[7:0] <= wrBus; end
|
|
|
|
3: begin SIZEB[10:8] <= wrBus[2:0]; end
|
|
|
|
default: begin we1 <= 1; end
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
else if(nSample)
|
|
|
|
begin SIZEB <= SIZEB - 1; end
|
|
|
|
else
|
|
|
|
begin we1 <= 0; end
|
|
|
|
// Read control
|
|
|
|
always @(posedge clk)
|
|
|
|
if(reset)
|
|
|
|
{rdBus} <= 0;
|
|
|
|
else begin
|
|
|
|
case (addr)
|
|
|
|
0: begin rdBus <= {CMD_DONE,CMD_TYP,CMD_ADC};end
|
|
|
|
1: begin rdBus <= CLKDIV; end
|
|
|
|
2: begin rdBus <= SIZEB[7:0]; end
|
|
|
|
3: begin rdBus <= SIZEB[10:8]; end
|
|
|
|
default: begin rdBus <= rdBus1; end
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
|
|
|
|
// Comunication control
|
2010-04-03 05:44:09 +03:00
|
|
|
always @(posedge clk)
|
|
|
|
if(reset)
|
2010-04-04 21:58:41 +03:00
|
|
|
{we2, SPI_wr, SPI_rd, w_st2, auto_count, SPI_in_data, nSample} <= 0;
|
2010-04-03 05:44:09 +03:00
|
|
|
else begin
|
|
|
|
case (w_st2)
|
2010-04-04 21:58:41 +03:00
|
|
|
0: begin w_st2 <= 2; SIZEB2<=SIZEB; end
|
2010-04-03 05:44:09 +03:00
|
|
|
2: begin
|
2010-04-04 21:58:41 +03:00
|
|
|
if (SIZEB == 0)
|
|
|
|
begin w_st2 <= 0; CMD_DONE<= 1; auto_count <= 0; end
|
2010-04-03 05:44:09 +03:00
|
|
|
else begin
|
2010-04-04 21:58:41 +03:00
|
|
|
CMD_DONE<= 0;
|
2010-04-03 05:44:09 +03:00
|
|
|
//Send data to ADC
|
2010-04-04 21:58:41 +03:00
|
|
|
auto_count <= auto_count+1;
|
|
|
|
SPI_in_data <= CMD_ADC[3:0];
|
|
|
|
SPI_wr <= 1; w_st2 <= 3;
|
2010-04-03 05:44:09 +03:00
|
|
|
end
|
|
|
|
end
|
|
|
|
3: begin
|
2010-04-04 21:58:41 +03:00
|
|
|
SPI_wr <= 0;
|
2010-04-03 05:44:09 +03:00
|
|
|
//Wait for complete convertion
|
|
|
|
if(!ADC_EOC || ADC_CS) begin
|
|
|
|
SPI_rd <=1;
|
2010-04-04 21:58:41 +03:00
|
|
|
if(CMD_TYP)
|
|
|
|
w_st2<= 2;
|
2010-04-03 05:44:09 +03:00
|
|
|
else
|
|
|
|
w_st2<= 4;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
4: begin
|
|
|
|
//Write data on BRAM (LOW)
|
|
|
|
wrBus2 <= SPI_out_data[7:0];
|
2010-04-04 21:58:41 +03:00
|
|
|
addr2 <= 4+2*(SIZEB2-SIZEB);
|
2010-04-03 05:44:09 +03:00
|
|
|
we2 <= 1; w_st2 <= 5;
|
|
|
|
end
|
2010-04-04 21:58:41 +03:00
|
|
|
5: begin we2 <= 0; w_st2 <= 6; end
|
2010-04-03 05:44:09 +03:00
|
|
|
6: begin
|
|
|
|
//Write data on BRAM (HI)
|
|
|
|
wrBus2 <= SPI_out_data[9:8];
|
2010-04-04 21:58:41 +03:00
|
|
|
addr2 <= 5+2*(SIZEB2-SIZEB);
|
|
|
|
we2 <= 1; w_st2 <= 7; nSample <= 1;
|
2010-04-03 05:44:09 +03:00
|
|
|
end
|
2010-04-04 21:58:41 +03:00
|
|
|
7: begin nSample <= 0; we2 <= 0; SPI_rd <=0; w_st2 <= 2; end
|
2010-04-03 05:44:09 +03:00
|
|
|
endcase
|
2010-04-03 07:30:52 +03:00
|
|
|
end
|
|
|
|
|
2010-04-04 21:58:41 +03:00
|
|
|
endmodule
|