xadc.sv (3893B)
1 // Copyright 2014 Travis Geiselbrecht <geist@foobox.com> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 `timescale 1ns / 1ps 16 17 module xadc( 18 input clk, 19 input rst, 20 21 input vp, 22 input vn, 23 input [15:0] aux_channel_n, 24 input [15:0] aux_channel_p, 25 26 output [3:0] debug_out, 27 28 axi_ifc.slave axi 29 ); 30 31 parameter reg [15:0] CLKDIV = 8; // default ADCCLK divide from input clk 32 parameter reg [15:0] CHSEL1 = 16'b0000000100000000; // CHSEL1 - enable temperature 33 parameter reg [15:0] CHSEL2 = 16'b0000000011000000; // CHSEL2 - enable simultaneous channels 6/14, 7/15 34 35 reg adc_den; 36 reg adc_dwe; 37 reg [15:0] adc_din; 38 wire [15:0] adc_dout; 39 reg [6:0] adc_daddr; 40 wire adc_drdy; 41 42 wire [4:0] adc_channel; 43 wire adc_eoc; 44 wire adc_eos; 45 wire adc_busy; 46 47 XADC #( 48 .INIT_40(16'b1000000000000000),// No averaging 49 .INIT_41(16'b0100111011110000),// Simultaneous sampling mode, Disable unused ALMs, Enable calibration 50 .INIT_42(16'b0000000000000000 | (CLKDIV << 8)),// DCLK divide 51 .INIT_48(CHSEL1), 52 .INIT_49(CHSEL2), 53 ) 54 adc0( 55 .DI(adc_din), // 16 bit in 56 .DO(adc_dout), // 16 bit out 57 .DADDR(adc_daddr), // 7 bit address 58 .DEN(adc_den), // enable 59 .DWE(adc_dwe), // write enable 60 .DCLK(clk), // clock 61 .DRDY(adc_drdy), // data ready out 62 .RESET(rst), // reset 63 .CONVST(0), // not used 64 .CONVSTCLK(0), // not used 65 66 .VN(vn), 67 .VP(vp), 68 .VAUXN(aux_channel_n[15:0]), 69 .VAUXP(aux_channel_p[15:0]), 70 71 .ALM(), // alarm outputs 72 .OT(), // over temp alarm output 73 74 .MUXADDR(),// not used 75 .CHANNEL(adc_channel), // channel output 76 77 .EOC(adc_eoc), // end of conversion 78 .EOS(adc_eos), // end of sequence 79 .BUSY(adc_busy), // busy during adc conversion 80 81 .JTAGBUSY(),// not used 82 .JTAGLOCKED(),// not used 83 .JTAGMODIFIED()// not used 84 ); 85 86 localparam ADC_REG_COUNT = 32; 87 localparam ADC_REG_COUNT_BITS = $clog2(ADC_REG_COUNT); 88 reg [15:0] adc_data [ADC_REG_COUNT]; 89 90 typedef enum { 91 WAIT_FOR_EOS, 92 READ_REG, 93 READ_REG_WAIT 94 } state_t; 95 96 state_t state = WAIT_FOR_EOS; 97 reg [ADC_REG_COUNT_BITS-1:0] reg_count; 98 99 /* wait for EOS then pull out readings from each ADC we care about */ 100 always_ff @(posedge clk) begin 101 adc_den = 0; 102 adc_dwe = 0; 103 adc_daddr = 0; 104 adc_din = 0; 105 106 if (rst) begin 107 state = WAIT_FOR_EOS; 108 for (int i = 0; i < ADC_REG_COUNT; i++) 109 adc_data[i] = 0; 110 end else begin 111 case (state) 112 WAIT_FOR_EOS: begin 113 reg_count = 0; 114 if (adc_eos) state = READ_REG; 115 end 116 READ_REG: begin 117 if (!adc_drdy) begin 118 adc_den = 1; 119 adc_daddr = { 2'b0, reg_count }; 120 state = READ_REG_WAIT; 121 end 122 end 123 READ_REG_WAIT: begin 124 if (adc_drdy) begin 125 adc_data[reg_count] <= adc_dout; 126 if (reg_count == ADC_REG_COUNT[ADC_REG_COUNT_BITS-1:0] - 1) begin 127 reg_count = 0; 128 state = WAIT_FOR_EOS; 129 end else begin 130 reg_count = reg_count + 1; 131 state = READ_REG; 132 end 133 end 134 end 135 endcase 136 end 137 end 138 139 /* AXI stuffs */ 140 wire [31:0]wdata; 141 reg [31:0]rdata; 142 wire [4:0]wreg; 143 wire [4:0]rreg; 144 wire wr; 145 wire rd; 146 147 axi_registers #( 148 .R_ADDR_WIDTH(5) 149 ) 150 regs( 151 .clk(clk), 152 .s(axi), 153 .o_rreg(rreg), 154 .o_wreg(wreg), 155 .i_rdata(rdata), 156 .o_wdata(wdata), 157 .o_rd(rd), 158 .o_wr(wr) 159 ); 160 161 always_comb begin 162 rdata = { 16'h0, adc_data[rreg[ADC_REG_COUNT_BITS-1:0]] }; 163 end 164 165 always_ff @(posedge clk) begin 166 if (wr) begin 167 case (wreg) 168 default: ; 169 endcase 170 end 171 end 172 173 assign debug_out[0] = adc_eoc; 174 assign debug_out[1] = adc_eos; 175 assign debug_out[2] = adc_busy; 176 assign debug_out[3] = 0; 177 178 endmodule 179 180 // vim: set noexpandtab: