1
0
mirror of git://projects.qi-hardware.com/nn-usb-fpga.git synced 2025-01-10 12:50:14 +02:00
nn-usb-fpga/Examples/ADC/logic/ADC_peripheral.v

254 lines
8.3 KiB
Coq
Raw Normal View History

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-05 22:06:50 +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-08 05:59:30 +03:00
reg ADC_CS=1;
2010-04-04 21:58:41 +03:00
//RAMB registers
reg [7:0] rdBus;
wire [7:0] rdBus1;
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;
2010-04-08 05:59:30 +03:00
2010-04-04 21:58:41 +03:00
//Control registers
2010-04-08 05:59:30 +03:00
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;
2010-04-04 21:58:41 +03:00
// Confiuration registers
2010-04-08 05:59:30 +03:00
reg CMD_START=0;
reg CMD_TYP=0;
reg [3:0] CMD_ADC=0;
2010-04-04 21:58:41 +03:00
reg [7:0] CLKDIV = 0;
2010-04-08 05:59:30 +03:00
reg [9:0] SIZEB=0; //[10:8] -> size_hi | [7:0] -> size_low
2010-04-04 21:58:41 +03:00
//TEMPS
2010-04-08 05:59:30 +03:00
reg [9:0] SIZEB2=0;
2010-04-04 21:58:41 +03:00
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-05 22:06:50 +03:00
.DOA(rdBus1), // Port A 8-bit Data Output
.DOB(), // Port B 8-bit Data Output
.DOPA(), // Port A 1-bit Parity Output
.DOPB(), // Port B 1-bit Parity Output
.ADDRA(addr), // Port A 11-bit Address Input
.ADDRB(addr2), // Port B 11-bit Address Input
.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 07:30:52 +03:00
2010-04-08 05:59:30 +03:00
//SPI registers
reg SPI_wr = 0;
2010-04-03 05:44:09 +03:00
reg ADC_SCLK_buffer = 0;
reg ADC_SDIN_buffer = 0;
2010-04-05 22:06:50 +03:00
reg busy = 0, load_in = 0;
reg pulse = 0, clkdiv_en = 0;
2010-04-08 05:59:30 +03:00
wire fallingSCLK;
2010-04-03 05:44:09 +03:00
reg [3:0] in_buffer=0;
reg [9:0] out_buffer;
reg [7:0] clkcount = 0;
2010-04-08 05:59:30 +03:00
reg [5:0] pulsecount = 0;
2010-04-05 22:06:50 +03:00
2010-04-08 05:59:30 +03:00
assign fallingSCLK = pulsecount[0];
2010-04-05 22:06:50 +03:00
2010-04-08 05:59:30 +03:00
// SPI Control
2010-04-05 22:06:50 +03:00
always @(posedge clk)
if(reset) begin
2010-04-08 05:59:30 +03:00
{w_st1, pulsecount, clkdiv_en, busy} <= 0;
2010-04-05 22:06:50 +03:00
end else begin
case (w_st1)
0: begin
if(SPI_wr) begin
2010-04-08 05:59:30 +03:00
clkdiv_en <= 1;
load_in <= 1;
w_st1 <= 1; busy <= 1;
end
2010-04-05 22:06:50 +03:00
end
1: begin
load_in <= 0;
if(pulse)
2010-04-08 05:59:30 +03:00
pulsecount <= pulsecount + 1;
else if (pulsecount > 55) begin
clkdiv_en <= 0; busy <= 0;
w_st1 <= 0; pulsecount <= 0;
end
2010-04-05 22:06:50 +03:00
end
endcase
end
2010-04-08 05:59:30 +03:00
// 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((pulsecount>0) && (pulsecount < 21))
ADC_SCLK_buffer <= ~ADC_SCLK_buffer;
end
end else begin
ADC_SCLK_buffer <= 0; pulse <=0;
end
// SPI Receptor
2010-04-05 22:06:50 +03:00
always@(posedge clk)
begin
2010-04-08 05:59:30 +03:00
if((fallingSCLK & pulse) && (pulsecount < 21)) begin
2010-04-05 22:06:50 +03:00
out_buffer <= out_buffer << 1;
out_buffer[0] <= ADC_SDOUT;
end
end
2010-04-08 05:59:30 +03:00
// SPI Transmitter
2010-04-05 22:06:50 +03:00
always@(posedge clk)
begin
2010-04-08 05:59:30 +03:00
if(load_in) in_buffer <= CMD_ADC[3:0];
if(!fallingSCLK & pulse) begin
2010-04-05 22:06:50 +03:00
ADC_SDIN_buffer <= in_buffer[3];
in_buffer <= in_buffer << 1;
end
end
assign ADC_SCLK = ADC_SCLK_buffer;
assign ADC_SDIN = ADC_SDIN_buffer;
2010-04-03 05:44:09 +03:00
2010-04-08 05:59:30 +03:00
/**************************************************************************/
2010-04-03 05:44:09 +03:00
2010-04-08 05:59:30 +03:00
// REGISTER BANK: Write control
2010-04-05 22:06:50 +03:00
always @(posedge clk)
2010-04-04 21:58:41 +03:00
if(reset)
2010-04-08 05:59:30 +03:00
{CMD_START, CMD_TYP,CMD_ADC,SIZEB,we1} <= 0;
2010-04-04 21:58:41 +03:00
else if(we & cs) begin
case (addr)
2010-04-08 05:59:30 +03:00
0: begin CMD_START <= wrBus[5];
CMD_TYP <= wrBus[4];
2010-04-04 21:58:41 +03:00
CMD_ADC[3:0] <= wrBus[3:0]; end
1: begin CLKDIV <= wrBus; end
2: begin SIZEB[7:0] <= wrBus; end
2010-04-08 05:59:30 +03:00
3: begin SIZEB[9:8] <= wrBus[1:0]; end
2010-04-05 22:06:50 +03:00
default: begin we1 <= 1; end
2010-04-04 21:58:41 +03:00
endcase
2010-04-08 05:59:30 +03:00
end else if(fullB || rstStart) begin
CMD_START <= 0; end
else begin
we1 <= 0; end
2010-04-05 22:06:50 +03:00
2010-04-08 05:59:30 +03:00
// REGISTER BANK: Read control
2010-04-04 21:58:41 +03:00
always @(posedge clk)
if(reset)
{rdBus} <= 0;
else begin
case (addr)
2010-04-08 05:59:30 +03:00
0: begin rdBus <= {CMD_START,CMD_TYP,CMD_ADC};end
2010-04-04 21:58:41 +03:00
1: begin rdBus <= CLKDIV; end
2: begin rdBus <= SIZEB[7:0]; end
2010-04-05 22:06:50 +03:00
3: begin rdBus <= SIZEB[9:8]; end
2010-04-04 21:58:41 +03:00
default: begin rdBus <= rdBus1; end
endcase
end
2010-04-08 05:59:30 +03:00
// 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
2010-04-03 05:44:09 +03:00
always @(posedge clk)
if(reset)
2010-04-08 05:59:30 +03:00
{we2, w_st2, fullB, SIZEB2} <= 0;
2010-04-03 05:44:09 +03:00
else begin
case (w_st2)
2010-04-08 05:59:30 +03:00
0: begin
fullB <= 0;
if(initB) begin
w_st2 <= 1;
SIZEB2<=SIZEB;
2010-04-05 22:06:50 +03:00
end
end
2010-04-08 05:59:30 +03:00
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
2010-04-05 22:06:50 +03:00
end
2010-04-08 05:59:30 +03:00
2: begin
2010-04-05 22:06:50 +03:00
//Write data on BRAM (LOW)
2010-04-08 05:59:30 +03:00
wrBus2 <= out_buffer[7:0];
2010-04-05 22:06:50 +03:00
addr2 <= 4+2*(SIZEB-SIZEB2);
2010-04-08 05:59:30 +03:00
we2 <= 1; w_st2 <= 3;
2010-04-05 22:06:50 +03:00
end
2010-04-08 05:59:30 +03:00
3: begin we2 <= 0; w_st2 <= 4; end
4: begin
2010-04-05 22:06:50 +03:00
//Write data on BRAM (HI)
2010-04-08 05:59:30 +03:00
wrBus2 <= out_buffer[9:8];
2010-04-05 22:06:50 +03:00
addr2 <= 5+2*(SIZEB-SIZEB2);
2010-04-08 05:59:30 +03:00
we2 <= 1; w_st2 <= 5;
2010-04-05 22:06:50 +03:00
end
2010-04-08 05:59:30 +03:00
5: begin
we2 <= 0; w_st2 <= 1; SIZEB2 <= SIZEB2-1;
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