mirror of
git://projects.qi-hardware.com/nn-usb-fpga.git
synced 2025-04-21 12:27:27 +03:00
Fixing ADC on high frequency.
This commit is contained in:
@@ -10,6 +10,8 @@ module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART,
|
||||
output [7:0] rdBus;
|
||||
inout ADC_SDIN, ADC_SDOUT;
|
||||
|
||||
reg ADC_CS=1;
|
||||
|
||||
//RAMB registers
|
||||
reg [7:0] rdBus;
|
||||
wire [7:0] rdBus1;
|
||||
@@ -18,27 +20,24 @@ module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART,
|
||||
reg we1=0;
|
||||
reg we2=0;
|
||||
wire we;
|
||||
|
||||
|
||||
//Control registers
|
||||
reg nSample=0;
|
||||
reg [10:0] auto_count=0;
|
||||
reg [4:0] w_st2=0;
|
||||
|
||||
|
||||
//SPI registers
|
||||
reg [3:0] SPI_in_data=0;
|
||||
reg [9:0] SPI_out_data;
|
||||
reg SPI_rd = 0;
|
||||
reg SPI_wr = 0;
|
||||
|
||||
reg loadB=0;
|
||||
reg initB=0;
|
||||
reg fullB=0;
|
||||
reg rstStart=0;
|
||||
reg [2:0] w_st0=0;
|
||||
reg w_st1=0;
|
||||
reg [2:0] w_st2=0;
|
||||
|
||||
// Confiuration registers
|
||||
reg CMD_DONE;
|
||||
reg CMD_TYP;
|
||||
reg [3:0] CMD_ADC;
|
||||
reg CMD_START=0;
|
||||
reg CMD_TYP=0;
|
||||
reg [3:0] CMD_ADC=0;
|
||||
reg [7:0] CLKDIV = 0;
|
||||
reg [9:0] SIZEB; //[10:8] -> size_hi | [7:0] -> size_low
|
||||
reg [9:0] SIZEB=0; //[10:8] -> size_hi | [7:0] -> size_low
|
||||
//TEMPS
|
||||
reg [9:0] SIZEB2;
|
||||
reg [9:0] SIZEB2=0;
|
||||
|
||||
assign ADC_CSTART = 1'b1;
|
||||
|
||||
@@ -63,77 +62,74 @@ module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART,
|
||||
.WEA(we1), // Port A Write Enable Input
|
||||
.WEB(we2) ); // Port B Write Enable Input
|
||||
|
||||
// SPI comunication module instantiation
|
||||
//SPI registers
|
||||
reg SPI_wr = 0;
|
||||
reg ADC_SCLK_buffer = 0;
|
||||
reg ADC_SDIN_buffer = 0;
|
||||
reg busy = 0, load_in = 0;
|
||||
reg pulse = 0, clkdiv_en = 0;
|
||||
wire fallingSCLK;
|
||||
|
||||
reg [3:0] in_buffer=0;
|
||||
reg [9:0] out_buffer;
|
||||
reg [7:0] clkcount = 0;
|
||||
reg [4:0] count = 0;
|
||||
reg [4:0] w_st1=0;
|
||||
reg [5:0] pulsecount = 0;
|
||||
|
||||
assign ADC_CS = ~busy;
|
||||
assign fallingSCLK = pulsecount[0];
|
||||
|
||||
// Clock Generator
|
||||
// SPI Control
|
||||
always @(posedge clk)
|
||||
if(reset) begin
|
||||
{w_st1, pulsecount, clkdiv_en, busy} <= 0;
|
||||
end else begin
|
||||
case (w_st1)
|
||||
0: begin
|
||||
if(SPI_wr) begin
|
||||
clkdiv_en <= 1;
|
||||
load_in <= 1;
|
||||
w_st1 <= 1; busy <= 1;
|
||||
end
|
||||
end
|
||||
1: begin
|
||||
load_in <= 0;
|
||||
if(pulse)
|
||||
pulsecount <= pulsecount + 1;
|
||||
else if (pulsecount > 55) begin
|
||||
clkdiv_en <= 0; busy <= 0;
|
||||
w_st1 <= 0; pulsecount <= 0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// SPI Clock Generator
|
||||
always@(posedge clk)
|
||||
if (clkdiv_en) begin
|
||||
if(clkcount < CLKDIV) begin
|
||||
clkcount <= clkcount + 1; pulse <=0;
|
||||
end else begin
|
||||
clkcount <= 0; pulse <=1;
|
||||
if((count>0) && (count < 21))
|
||||
if((pulsecount>0) && (pulsecount < 21))
|
||||
ADC_SCLK_buffer <= ~ADC_SCLK_buffer;
|
||||
end
|
||||
end else begin
|
||||
ADC_SCLK_buffer <= 0; pulse <=0;
|
||||
end
|
||||
// Control
|
||||
always @(posedge clk)
|
||||
if(reset) begin
|
||||
{w_st1, count, clkdiv_en, busy} <= 0;
|
||||
end else begin
|
||||
case (w_st1)
|
||||
0: begin
|
||||
if(SPI_wr) begin
|
||||
clkdiv_en <= 1;
|
||||
load_in <= 1;
|
||||
w_st1 <= 1; busy <= 1;
|
||||
end
|
||||
end
|
||||
1: begin
|
||||
load_in <= 0;
|
||||
if(pulse)
|
||||
count <= count + 1;
|
||||
else if (count > 30) begin
|
||||
clkdiv_en <= 0; busy <= 0; w_st1 <= 0; count <= 0; end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// Receptor
|
||||
// SPI Receptor
|
||||
always@(posedge clk)
|
||||
begin
|
||||
if((count[0] & pulse) && (count < 21)) begin
|
||||
if((fallingSCLK & pulse) && (pulsecount < 21)) begin
|
||||
out_buffer <= out_buffer << 1;
|
||||
out_buffer[0] <= ADC_SDOUT;
|
||||
end
|
||||
end
|
||||
|
||||
always@(SPI_rd or out_buffer or busy or CLKDIV)
|
||||
begin
|
||||
SPI_out_data <= 10'bx;
|
||||
if(SPI_rd)
|
||||
begin SPI_out_data <= out_buffer; end
|
||||
end
|
||||
|
||||
// Transmitter
|
||||
// SPI Transmitter
|
||||
always@(posedge clk)
|
||||
begin
|
||||
if(load_in) in_buffer <= SPI_in_data;
|
||||
if(!count[0] & pulse) begin
|
||||
if(load_in) in_buffer <= CMD_ADC[3:0];
|
||||
if(!fallingSCLK & pulse) begin
|
||||
ADC_SDIN_buffer <= in_buffer[3];
|
||||
in_buffer <= in_buffer << 1;
|
||||
end
|
||||
@@ -141,86 +137,35 @@ module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART,
|
||||
|
||||
assign ADC_SCLK = ADC_SCLK_buffer;
|
||||
assign ADC_SDIN = ADC_SDIN_buffer;
|
||||
|
||||
/*
|
||||
assign ADC_CS = ~busy;
|
||||
|
||||
always@(SPI_rd or out_buffer or busy or CLKDIV)
|
||||
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;
|
||||
if(clkcount >= CLKDIV)
|
||||
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;*/
|
||||
|
||||
// Write control
|
||||
// REGISTER BANK: Write control
|
||||
always @(posedge clk)
|
||||
if(reset)
|
||||
{CMD_TYP,CMD_ADC,SIZEB,we1} <= 0;
|
||||
{CMD_START, CMD_TYP,CMD_ADC,SIZEB,we1} <= 0;
|
||||
else if(we & cs) begin
|
||||
case (addr)
|
||||
0: begin CMD_TYP <= wrBus[4];
|
||||
0: begin CMD_START <= wrBus[5];
|
||||
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[9:8] <= wrBus[2:0]; end
|
||||
3: begin SIZEB[9:8] <= wrBus[1:0]; end
|
||||
default: begin we1 <= 1; end
|
||||
endcase
|
||||
end
|
||||
else if(nSample)
|
||||
begin SIZEB <= SIZEB - 1; end
|
||||
else
|
||||
begin we1 <= 0; end
|
||||
end else if(fullB || rstStart) begin
|
||||
CMD_START <= 0; end
|
||||
else begin
|
||||
we1 <= 0; end
|
||||
|
||||
// Read control
|
||||
// REGISTER BANK: Read control
|
||||
always @(posedge clk)
|
||||
if(reset)
|
||||
{rdBus} <= 0;
|
||||
else begin
|
||||
case (addr)
|
||||
0: begin rdBus <= {CMD_DONE,CMD_TYP,CMD_ADC};end
|
||||
0: begin rdBus <= {CMD_START,CMD_TYP,CMD_ADC};end
|
||||
1: begin rdBus <= CLKDIV; end
|
||||
2: begin rdBus <= SIZEB[7:0]; end
|
||||
3: begin rdBus <= SIZEB[9:8]; end
|
||||
@@ -228,49 +173,80 @@ module ADC_peripheral( clk, reset, cs, ADC_EOC, ADC_CS, ADC_CSTART,
|
||||
endcase
|
||||
end
|
||||
|
||||
// Comunication control
|
||||
// CONTROL
|
||||
always @(posedge clk)
|
||||
if(reset)
|
||||
{w_st0, SPI_wr} <= 0;
|
||||
else begin
|
||||
case (w_st0)
|
||||
0: begin
|
||||
rstStart <= 0; loadB <= 0; ADC_CS <=0; initB<=0;
|
||||
if(CMD_START) begin
|
||||
initB<=1;
|
||||
w_st0 <=1;
|
||||
end
|
||||
end
|
||||
1: begin
|
||||
SPI_wr <= 1; w_st0 <=2;
|
||||
end
|
||||
2: begin
|
||||
SPI_wr <= 0;
|
||||
if(!busy && ADC_EOC) begin
|
||||
ADC_CS <=1;
|
||||
if(CMD_TYP) begin
|
||||
rstStart <= 1;
|
||||
w_st0<= 0;
|
||||
end
|
||||
else begin
|
||||
loadB <= 1;
|
||||
w_st0<= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
// Reception Buffer
|
||||
always @(posedge clk)
|
||||
if(reset)
|
||||
{we2, SPI_wr, SPI_rd, w_st2, auto_count, SPI_in_data, nSample} <= 0;
|
||||
{we2, w_st2, fullB, SIZEB2} <= 0;
|
||||
else begin
|
||||
case (w_st2)
|
||||
0: begin w_st2 <= 2; SIZEB2<=SIZEB; end
|
||||
2: begin
|
||||
if (SIZEB == 0)
|
||||
begin w_st2 <= 0; CMD_DONE<= 1; auto_count <= 0; end
|
||||
else begin
|
||||
CMD_DONE<= 0;
|
||||
//Send data to ADC
|
||||
auto_count <= auto_count+1;
|
||||
SPI_in_data <= CMD_ADC[3:0];
|
||||
SPI_wr <= 1; w_st2 <= 3;
|
||||
0: begin
|
||||
fullB <= 0;
|
||||
if(initB) begin
|
||||
w_st2 <= 1;
|
||||
SIZEB2<=SIZEB;
|
||||
end
|
||||
end
|
||||
3: begin
|
||||
SPI_wr <= 0;
|
||||
//Wait for complete convertion
|
||||
if(ADC_CS && ADC_EOC) begin
|
||||
SPI_rd <=1;
|
||||
if(CMD_TYP)
|
||||
w_st2<= 2;
|
||||
else
|
||||
w_st2<= 4;
|
||||
end
|
||||
1: begin
|
||||
if(loadB) begin
|
||||
// If buffer full set fullB flag by a clock cicle
|
||||
if(SIZEB2) begin
|
||||
w_st2 <= 2; end
|
||||
else begin
|
||||
fullB <= 1;
|
||||
w_st2 <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
4: begin
|
||||
2: begin
|
||||
//Write data on BRAM (LOW)
|
||||
wrBus2 <= SPI_out_data[7:0];
|
||||
wrBus2 <= out_buffer[7:0];
|
||||
addr2 <= 4+2*(SIZEB-SIZEB2);
|
||||
we2 <= 1; w_st2 <= 5;
|
||||
we2 <= 1; w_st2 <= 3;
|
||||
end
|
||||
5: begin we2 <= 0; w_st2 <= 6; end
|
||||
6: begin
|
||||
3: begin we2 <= 0; w_st2 <= 4; end
|
||||
4: begin
|
||||
//Write data on BRAM (HI)
|
||||
wrBus2 <= SPI_out_data[9:8];
|
||||
wrBus2 <= out_buffer[9:8];
|
||||
addr2 <= 5+2*(SIZEB-SIZEB2);
|
||||
we2 <= 1; w_st2 <= 7; nSample <= 1;
|
||||
we2 <= 1; w_st2 <= 5;
|
||||
end
|
||||
7: begin nSample <= 0; we2 <= 0; SPI_rd <=0; w_st2 <= 2; end
|
||||
5: begin
|
||||
we2 <= 0; w_st2 <= 1; SIZEB2 <= SIZEB2-1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user