From 0b5d03e1e6e05de0c1223cbb358e7e076cf36fce Mon Sep 17 00:00:00 2001 From: Carlos Camargo Date: Fri, 2 Apr 2010 21:44:09 -0500 Subject: [PATCH] Adding ADC example --- Examples/ADC/logic/ADC.ucf | 41 +++++++ Examples/ADC/logic/ADC.v | 104 ++++++++++++++++++ Examples/ADC/logic/ADC_peripheral.v | 161 ++++++++++++++++++++++++++++ Examples/ADC/logic/Makefile | 74 +++++++++++++ 4 files changed, 380 insertions(+) create mode 100644 Examples/ADC/logic/ADC.ucf create mode 100644 Examples/ADC/logic/ADC.v create mode 100644 Examples/ADC/logic/ADC_peripheral.v create mode 100644 Examples/ADC/logic/Makefile diff --git a/Examples/ADC/logic/ADC.ucf b/Examples/ADC/logic/ADC.ucf new file mode 100644 index 0000000..1590c1f --- /dev/null +++ b/Examples/ADC/logic/ADC.ucf @@ -0,0 +1,41 @@ +NET clk LOC = "P38"; +NET reset LOC = "P71"; #WARNING change to another pin +NET led LOC = "P44"; + +#ADDRESS BUS +#NET "addr<12>" LOC = "P90"; +#NET "addr<11>" LOC = "P91"; +NET "addr<10>" LOC = "P85"; +NET "addr<9>" LOC = "P92"; +NET "addr<8>" LOC = "P94"; +NET "addr<7>" LOC = "P95"; +NET "addr<6>" LOC = "P98"; +NET "addr<5>" LOC = "P3"; +NET "addr<4>" LOC = "P2"; +NET "addr<3>" LOC = "P78"; +NET "addr<2>" LOC = "P79"; +NET "addr<1>" LOC = "P83"; +NET "addr<0>" LOC = "P84"; + +#DATA BUS +NET "sram_data<7>" LOC = "P4"; +NET "sram_data<6>" LOC = "P5"; +NET "sram_data<5>" LOC = "P9"; +NET "sram_data<4>" LOC = "P10"; +NET "sram_data<3>" LOC = "P11"; +NET "sram_data<2>" LOC = "P12"; +NET "sram_data<1>" LOC = "P15"; +NET "sram_data<0>" LOC = "P16"; + +#CONTROL BUS +NET "nwe" LOC = "P88"; +NET "noe" LOC = "P86"; +NET "ncs" LOC = "P69"; + +#ADC +NET "ADC_EOC" LOC = "P17"; +NET "ADC_SCLK" LOC = "P18" ; +NET "ADC_SDIN" LOC = "P22"; +NET "ADC_SDOUT" LOC = "P23"; +NET "ADC_CS" LOC = "P24"; +NET "ADC_CSTART" LOC = "P26"; \ No newline at end of file diff --git a/Examples/ADC/logic/ADC.v b/Examples/ADC/logic/ADC.v new file mode 100644 index 0000000..3565487 --- /dev/null +++ b/Examples/ADC/logic/ADC.v @@ -0,0 +1,104 @@ +`timescale 1ns / 1ps +module ADC(clk, sram_data, addr, nwe, ncs, noe, reset, led, ADC_EOC, + ADC_SCLK, ADC_SDIN, ADC_SDOUT, ADC_CS, ADC_CSTART); + + parameter B = (7); + + input clk, addr, nwe, ncs, noe, reset, ADC_EOC; + inout [B:0] sram_data; + output led, ADC_CS, ADC_CSTART, ADC_SCLK; + inout ADC_SDIN, ADC_SDOUT; + + + // Internal conection + reg led; + + // synchronize signals + reg sncs, snwe; + reg [10:0] buffer_addr; + wire [8:0] addr2; + reg [B:0] buffer_data; + + // interfaz fpga signals + wire [10:0] addr; + + // bram interfaz signals + reg we; + wire we2; + reg w_st=0; + reg [B:0] wrBus; + wire [B:0] rdBus; + wire [B:0] wrBus2; + wire [B:0] rdBus2; + + reg [25:0] counter; + + // Test : LED blinking + always @(posedge clk) begin + if (reset) + counter <= {25{1'b0}}; + else + counter <= counter + 1; + led <=counter[25]; + end + + // interefaz signals assignments + wire T = ~noe | ncs; + assign sram_data = T?8'bZ:rdBus; + + // synchronize assignment + always @(negedge clk) + begin + sncs <= ncs; + snwe <= nwe; + buffer_data <= sram_data; + buffer_addr <= addr; + end + + // write access cpu to bram + always @(posedge clk) + if(reset) {w_st, we, wrBus} <= 0; + else begin + wrBus <= buffer_data; + case (w_st) + 0: begin + we <= 0; + if(sncs | snwe) w_st <= 1; + end + 1: begin + if(~(sncs | snwe)) begin + we <= 1; + w_st <= 0; + end + else we <= 0; + end + endcase + end + + // Dual-port RAM instatiation + RAMB16_S9_S9 ba0( + .DOA(rdBus), // Port A 8-bit Data Output + .DOB(rdBus2), // Port B 8-bit Data Output + .DOPA(), // Port A 1-bit Parity Output + .DOPB(), // Port B 1-bit Parity Output + .ADDRA(buffer_addr[10:0]), // Port A 11-bit Address Input + .ADDRB(addr2[8:0]), // 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(we), // Port A Write Enable Input + .WEB(we2) ); // Port B Write Enable Input + + // Peripheral instantiation + ADC_peripheral P1( clk, reset, ADC_EOC, ADC_CS, ADC_CSTART, + ADC_SCLK, ADC_SDIN, ADC_SDOUT, we2, + rdBus2, wrBus2, addr2); +endmodule + diff --git a/Examples/ADC/logic/ADC_peripheral.v b/Examples/ADC/logic/ADC_peripheral.v new file mode 100644 index 0000000..4ddcd4e --- /dev/null +++ b/Examples/ADC/logic/ADC_peripheral.v @@ -0,0 +1,161 @@ +`timescale 1ns / 1ps +module ADC_peripheral( clk, reset, ADC_EOC, ADC_CS, ADC_CSTART, + ADC_SCLK, ADC_SDIN, ADC_SDOUT, we2, + rdBus2, wrBus2, addr2); + + input clk, reset, ADC_EOC; + input [7:0] rdBus2; + output we2, ADC_CS, ADC_CSTART, ADC_SCLK; + output [7:0] wrBus2; + output [8:0] addr2; + inout ADC_SDIN, ADC_SDOUT; + + reg we2=0, nSample=0; + reg [7:0] wrBus2; + reg [8:0] addr2; + reg [7:0] auto_count=0; + reg [4:0] w_st2=0; + reg [3:0] SPI_in_data=0; + reg [9:0] SPI_out_data; + reg SPI_rd = 0; + reg SPI_wr = 0; + reg [7:0] buffer_rd1; + reg [3:0] ADC_cmd; + + assign ADC_CSTART = 1'b1; + + // 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 [7:0] clkdiv = 255; + reg [4:0] count = 0; + + 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; + + // State Machine for control ADC comunication + always @(posedge clk) + if(reset) + {we2, SPI_wr, SPI_rd, w_st2, auto_count, SPI_in_data} <= 0; + else begin + case (w_st2) + 0: begin addr2 <= 0; w_st2 <= 1; end + 1: begin + ADC_cmd <= rdBus2[3:0]; + if (rdBus2[7:4] == 5) + // Send command without read samples + begin addr2<= 2; w_st2 <= 2; nSample <= 1; end + else if (rdBus2[7:4] == 6) + // Read: Stop when buffer full + begin addr2<= 2; w_st2 <= 2; nSample <= 0; end + else if (rdBus2[7:4] == 9) + // Set clkdiv on SPI controller + begin addr2<= 1; w_st2 <= 10; end + else + begin w_st2 <= 0; end + end + 2: begin + if (rdBus2[7:0] == 0) + begin auto_count<=0; w_st2 <= 0; end + else begin + //Send data to ADC + buffer_rd1<=rdBus2; + auto_count<=auto_count+1; + SPI_in_data <= ADC_cmd[3:0]; + SPI_wr <= 1; w_st2 <= 3; + end + end + 3: begin + SPI_wr <= 0; + //Wait for complete convertion + if(!ADC_EOC || ADC_CS) begin + buffer_rd1<=buffer_rd1-1; + SPI_rd <=1; + if(nSample) + w_st2<= 8; + else + w_st2<= 4; + end + end + 4: begin + //Write data on BRAM (LOW) + wrBus2 <= SPI_out_data[7:0]; + addr2 <= 2+2*auto_count; + we2 <= 1; w_st2 <= 5; + end + 5: begin we2 <= 0; w_st2 <= 6; end + 6: begin + //Write data on BRAM (HI) + wrBus2 <= SPI_out_data[9:8]; + addr2 <= 3+2*auto_count; + we2 <= 1; w_st2 <= 7; + end + 7: begin we2 <= 0; w_st2 <= 8; end + 8: begin + SPI_rd <=0; + //Update Buffer Size value + wrBus2 <= buffer_rd1; + addr2 <= 2; + we2 <= 1; w_st2 <= 9; + end + 9: begin we2 <= 0; w_st2 <= 0; end + + //Sent clock divider for speed on SPI comunication + 10: begin clkdiv = rdBus2; w_st2 <= 0; end + endcase + end + endmodule diff --git a/Examples/ADC/logic/Makefile b/Examples/ADC/logic/Makefile new file mode 100644 index 0000000..af4144b --- /dev/null +++ b/Examples/ADC/logic/Makefile @@ -0,0 +1,74 @@ +DESIGN = ADC +PINS = $(DESIGN).ucf +DEVICE = xc3s250e-VQ100-4 +BGFLAGS = -g TdoPin:PULLNONE -g DonePin:PULLUP \ + -g CRC:enable -g StartUpClk:CCLK + +SIM_CMD = /opt/cad/modeltech/bin/vsim +SIM_COMP_SCRIPT = simulation/$(DESIGN)_TB.do +#SIM_INIT_SCRIPT = simulation/$(DESIGN)_init.do +SIMGEN_OPTIONS = -p $(FPGA_ARCH) -lang $(LANGUAGE) +SAKC_IP = 192.168.254.101 + +SRC = $(DESIGN).v ADC_peripheral.v + +all: bits + +remake: clean-build all + +clean: + rm -f *~ */*~ a.out *.log *.key *.edf *.ps trace.dat + rm *.bit + +clean-build: clean + rm -rf build + +cleanall: clean + rm -rf build $(DESIGN).bit + +bits: $(DESIGN).bit + +# +# Synthesis +# +build/project.src: + @[ -d build ] || mkdir build + @rm -f $@ + for i in $(SRC); do echo verilog work ../$$i >> $@; done + for i in $(SRC_HDL); do echo VHDL work ../$$i >> $@; done + +build/project.xst: build/project.src + echo "run" > $@ + echo "-top $(DESIGN) " >> $@ + echo "-p $(DEVICE)" >> $@ + echo "-opt_mode Area" >> $@ + echo "-opt_level 1" >> $@ + echo "-ifn project.src" >> $@ + echo "-ifmt mixed" >> $@ + echo "-ofn project.ngc" >> $@ + echo "-ofmt NGC" >> $@ + echo "-rtlview yes" >> $@ + +build/project.ngc: build/project.xst $(SRC) + cd build && xst -ifn project.xst -ofn project.log + +build/project.ngd: build/project.ngc $(PINS) + cd build && ngdbuild -p $(DEVICE) project.ngc -uc ../$(PINS) + +build/project.ncd: build/project.ngd + cd build && map -pr b -p $(DEVICE) project + +build/project_r.ncd: build/project.ncd + cd build && par -w project project_r.ncd + +build/project_r.twr: build/project_r.ncd + cd build && trce -v 25 project_r.ncd project.pcf + +$(DESIGN).bit: build/project_r.ncd build/project_r.twr + cd build && bitgen project_r.ncd -l -w $(BGFLAGS) + @mv -f build/project_r.bit $@ +sim: + cd simulation; $(SIM_CMD) -do $(DESIGN)_TB.do + +upload: $(DESIGN).bit + scp $(DESIGN).bit root@$(SAKC_IP):