/* * lab12_adc_linear.v * demonstrate single-slope ADC operation for physics 364 week 12 * begun 2010-11-28 * by Bill Ashmanskas, ashmansk@hep.upenn.edu */ `default_nettype none `timescale 1ns/1ns /* * Implement single-slope ADC */ module adc ( input wire clk, // 68 kHz clock, for 1 kHz sample rate input wire cmp, // 1 if sample > DAC value, else 0 output wire [5:0] dac, // DAC used for comparing with sample output wire [5:0] adc, // ADC output value output wire conv_done, // indicate next ADC value is ready output wire sample_hold // closes FET switch for sample & hold ); // modulo-68 counter: ramp 0..63, then allow 4 extra ticks for processing wire [6:0] count; wire [6:0] count_next = (count==67) ? 0 : count+1; dffe_Nbit #(7) count_ff (.clk(clk), .ena(1), .d(count_next), .q(count)); // ramp the DAC output during the 0..63 phase of counter assign dac = count[6] ? 0 : count[5:0]; // new ADC value will be the largest DAC value for which sample>DAC wire [5:0] newadc; dffe_Nbit #(6) newadc_ff (.clk(clk), .ena(cmp), .d(dac), .q(newadc)); // when 0..63 ramp is complete, copy newadc into ADC output register dffe_Nbit #(6) adc_ff (.clk(clk), .ena(count==64), .d(newadc), .q(adc)); // when ADC output register has updated, strobe "conversion done" signal assign conv_done = (count==65); // before new ramp begins, tell sample & hold to get new sample assign sample_hold = (count==66); endmodule /* * Test bench for ADC */ module adc_tb; reg clk=0, cmp=0; wire [5:0] adc, dac; wire conv_done, sample_hold; adc uut (.clk(clk), .cmp(cmp), .adc(adc), .dac(dac), .conv_done(conv_done), .sample_hold(sample_hold)); parameter period=1000000/68; initial begin #200; forever begin #(period/2); clk = 1; #(period/2); clk = 0; end end reg [5:0] sample = 0; always @(*) begin cmp = (sample>=dac); if (sample_hold) sample = sample+13; end always @ (negedge clk) begin $display("t=%1d done=%1d sample=%1d dac=%1d cmp=%1d adc=%1d", $time/period, conv_done, sample, dac, cmp, adc); end initial begin #(65*1000000); $finish; end endmodule /* * Implement N-bit-wide D-type flip-flop, with enable */ module dffe_Nbit #(parameter N=1) ( input wire clk, input wire ena, input wire [N-1:0] d, output wire [N-1:0] q ); reg [N-1:0] qreg=0; always @ (posedge clk) begin if (ena) qreg <= d; end assign q = qreg; endmodule