fpga: ADC Select Feature Allow the selection of which ADC channels are sampled when in continuous read mode. Change-Id: Ic7911efc9bfb006099f3a7e6608e5ab782f51ba2 Reviewed-on: https://pigweed-review.googlesource.com/c/gonk/+/190017 Reviewed-by: Umang Shah <umangshah@google.com> Commit-Queue: Anthony DiGirolamo <tonymd@google.com>
diff --git a/fpga/gonk/csa_ctl_top.v b/fpga/gonk/csa_ctl_top.v index 5d8609c..e0b5644 100644 --- a/fpga/gonk/csa_ctl_top.v +++ b/fpga/gonk/csa_ctl_top.v
@@ -25,6 +25,7 @@ input en_i, input mode_i, input [10:0] adc_sel_i, + input [10:0] poll_adc_en_i, input [5:0] rwaddr_i, input [15:0] wdata_i, output reg dn_o, @@ -186,6 +187,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[0]), .dn_o(dn_r1), .rdata_o(rdata_w1), .vbus_o(vbus_1), @@ -207,6 +209,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[1]), .dn_o(dn_r2), .rdata_o(rdata_w2), .vbus_o(vbus_2), @@ -228,6 +231,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[2]), .dn_o(dn_r3), .rdata_o(rdata_w3), .vbus_o(vbus_3), @@ -249,6 +253,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[3]), .dn_o(dn_r4), .rdata_o(rdata_w4), .vbus_o(vbus_4), @@ -270,6 +275,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[4]), .dn_o(dn_r5), .rdata_o(rdata_w5), .vbus_o(vbus_5), @@ -292,6 +298,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[5]), .dn_o(dn_r6), .rdata_o(rdata_w6), .vbus_o(vbus_6), @@ -313,6 +320,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[6]), .dn_o(dn_r7), .rdata_o(rdata_w7), .vbus_o(vbus_7), @@ -334,6 +342,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[7]), .dn_o(dn_r8), .rdata_o(rdata_w8), .vbus_o(vbus_8), @@ -355,6 +364,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[8]), .dn_o(dn_r9), .rdata_o(rdata_w9), .vbus_o(vbus_9), @@ -376,6 +386,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[9]), .dn_o(dn_r10), .rdata_o(rdata_w10), .vbus_o(vbus_10), @@ -397,6 +408,7 @@ .mode_i(mode_i), .rwaddr_i(rwaddr_r), .wdata_i(wdata_r), + //.poll_en_i(poll_adc_en_i[10]), .dn_o(dn_r11), .rdata_o(rdata_w11), .vbus_o(vbus_11), @@ -553,27 +565,69 @@ /// - reg poll_dn_latch_0_r, poll_dn_latch_1_r, poll_dn_latch_2_r, poll_dn_latch_3_r; - wire poll_dn_latch_0, poll_dn_latch_1, poll_dn_latch_2, poll_dn_latch_3, poll_dn_w; + reg poll_dn_latch_1_r, poll_dn_latch_2_r, poll_dn_latch_3_r; + reg poll_dn_latch_4_r, poll_dn_latch_5_r, poll_dn_latch_6_r, poll_dn_latch_7_r; + reg poll_dn_latch_8_r, poll_dn_latch_9_r, poll_dn_latch_10_r, poll_dn_latch_11_r; - assign poll_dn_latch_0 = (poll_dn_latch_r7 & poll_dn_latch_r9 & poll_dn_latch_r10); // bank0 - assign poll_dn_latch_1 = (poll_dn_latch_r5 & poll_dn_latch_r8 & poll_dn_latch_r1); - assign poll_dn_latch_2 = (poll_dn_latch_r4 & poll_dn_latch_r6 & poll_dn_latch_r3); - assign poll_dn_latch_3 = (poll_dn_latch_r2 & poll_dn_latch_r11); - assign poll_dn_w = (poll_dn_latch_0_r & poll_dn_latch_1_r & poll_dn_latch_2_r & poll_dn_latch_3_r); + wire poll_dn_latch_0, poll_dn_latch_1, poll_dn_latch_2, poll_dn_latch_3, poll_dn_w; + wire poll_dn_latch_4, poll_dn_latch_5, poll_dn_latch_6, poll_dn_latch_7; + wire poll_dn_latch_8, poll_dn_latch_9, poll_dn_latch_10, poll_dn_sync0, poll_dn_sync1,poll_dn_sync2,poll_dn_sync3 ; + + reg poll_dn_sync0_r, poll_dn_sync1_r, poll_dn_sync2_r, poll_dn_sync3_r; + + assign poll_dn_latch_0 = (poll_dn_latch_r1 | (!poll_adc_en_i[0])); + assign poll_dn_latch_1 = (poll_dn_latch_r2 | (!poll_adc_en_i[1])); + assign poll_dn_latch_2 = (poll_dn_latch_r3 | (!poll_adc_en_i[2])); + assign poll_dn_latch_3 = (poll_dn_latch_r4 | (!poll_adc_en_i[3])); + assign poll_dn_latch_4 = (poll_dn_latch_r5 | (!poll_adc_en_i[4])); + assign poll_dn_latch_5 = (poll_dn_latch_r6 | (!poll_adc_en_i[5])); + assign poll_dn_latch_6 = (poll_dn_latch_r7 | (!poll_adc_en_i[6])); + assign poll_dn_latch_7 = (poll_dn_latch_r8 | (!poll_adc_en_i[7])); + assign poll_dn_latch_8 = (poll_dn_latch_r9 | (!poll_adc_en_i[8])); + assign poll_dn_latch_9 = (poll_dn_latch_r10 | (!poll_adc_en_i[9])); + assign poll_dn_latch_10 = (poll_dn_latch_r11 | (!poll_adc_en_i[10])); + + assign poll_dn_sync0 = (poll_dn_latch_7_r & poll_dn_latch_9_r & poll_dn_latch_10_r); // bank0 + assign poll_dn_sync1 = (poll_dn_latch_5_r & poll_dn_latch_8_r & poll_dn_latch_1_r); + assign poll_dn_sync2 = (poll_dn_latch_4_r & poll_dn_latch_6_r & poll_dn_latch_3_r); + assign poll_dn_sync3 = (poll_dn_latch_2_r & poll_dn_latch_11_r); + + assign poll_dn_w = poll_dn_sync0 & poll_dn_sync1 & poll_dn_sync2 & poll_dn_sync3; always @(posedge mclk_i) begin if (rst_i_r) begin poll_dn_r <= 0; - poll_dn_latch_0_r <= 0; poll_dn_latch_1_r <= 0; poll_dn_latch_2_r <= 0; poll_dn_latch_3_r <= 0; + poll_dn_latch_4_r <= 0; + poll_dn_latch_5_r <= 0; + poll_dn_latch_6_r <= 0; + poll_dn_latch_7_r <= 0; + poll_dn_latch_8_r <= 0; + poll_dn_latch_9_r <= 0; + poll_dn_latch_10_r <= 0; + poll_dn_latch_11_r <= 0; + poll_dn_sync0_r <= 0; + poll_dn_sync1_r <= 0; + poll_dn_sync2_r <= 0; + poll_dn_sync3_r <= 0; end else begin - poll_dn_latch_0_r <= poll_dn_latch_0; - poll_dn_latch_1_r <= poll_dn_latch_1; - poll_dn_latch_2_r <= poll_dn_latch_2; - poll_dn_latch_3_r <= poll_dn_latch_3; + poll_dn_latch_1_r <= poll_dn_latch_0; + poll_dn_latch_2_r <= poll_dn_latch_1; + poll_dn_latch_3_r <= poll_dn_latch_2; + poll_dn_latch_4_r <= poll_dn_latch_3; + poll_dn_latch_5_r <= poll_dn_latch_4; + poll_dn_latch_6_r <= poll_dn_latch_5; + poll_dn_latch_7_r <= poll_dn_latch_6; + poll_dn_latch_8_r <= poll_dn_latch_7; + poll_dn_latch_9_r <= poll_dn_latch_8; + poll_dn_latch_10_r <= poll_dn_latch_9; + poll_dn_latch_11_r <= poll_dn_latch_10; + poll_dn_sync0_r <= poll_dn_sync0; + poll_dn_sync1_r <= poll_dn_sync1; + poll_dn_sync2_r <= poll_dn_sync2; + poll_dn_sync3_r <= poll_dn_sync3; poll_dn_r <= poll_dn_w; end end
diff --git a/fpga/gonk/spi_s_core.v b/fpga/gonk/spi_s_core.v index d8f1af0..35093e9 100644 --- a/fpga/gonk/spi_s_core.v +++ b/fpga/gonk/spi_s_core.v
@@ -51,6 +51,7 @@ output reg [5:0] rwaddr_o, output reg [15:0] wdata_o, output reg [10:0] adc_sel_o, + output [10:0] poll_adc_en_o, // sys input mclk_i, input rst_i, @@ -66,6 +67,9 @@ localparam IDLE = 1; localparam WT = 2; localparam DN = 4; + localparam S0 = 1; + localparam S1 = 2; + localparam S2 = 4; reg sclk_i_r0, @@ -79,7 +83,8 @@ mosi_i_r2, dat_out_dn_r, rst_i_r, - wr_dn_valid_r; + wr_dn_valid_r, + poll_adc_sel_valid_r; reg spi_rdy_r, dat_out_dn_latch, @@ -90,21 +95,28 @@ wdata_rdy_r, dat_out_ctr_clr_r, poll_ctr_en_r, - poll_ctr_en_r1; - reg [2:0] spi_s_state; + poll_ctr_en_r1, + addr_rdy_r1, + poll_adc_sel_en_r; + reg [2:0] spi_s_state, poll_adc_state, dat_out_dn_latch_ctr; + reg [3:0] adc_count, poll_dat_next_ctr_index_r; // Number of ADCs enabled for continous polling. + reg [4:0] i; reg [5:0] rwaddr_latch_r, poll_dat_ctr_r; reg [6:0] dat_in_ctr_r, data_count_max_r, dat_out_ctr; + reg [10:0] poll_adc_sel_r; reg [15:0] rwaddr_r, wdata_r, wdata_latch_r, poll_dat_bits_ctr_r; reg [23:0] poll_dat_r; reg [39:0] dat_in_r, dat_out_r, dat_in_r1; wire pos_edge, neg_edge, poll_ctr_en_w; + reg [4:0] poll_dat_next_ctr_r[11:0]; // Holds the index of valid ADCs for continous polling. + assign pos_edge = (sclk_i_r1 & !sclk_i_r2); assign neg_edge = (!sclk_i_r1 & sclk_i_r2); assign poll_ctr_en_w = dat_out_ctr_clr_r & dat_out_ctr_clr; assign data_valid_o = (dat_out_en_r | wr_dn_valid_r); - + assign poll_adc_en_o = poll_adc_sel_r; always @(posedge mclk_i) begin rst_i_r <= rst_i; @@ -115,7 +127,6 @@ {sclk_i_r0, sclk_i_r1, sclk_i_r2} <= 0; {cs_i_r0, cs_i_r1, cs_i_r2} <= 3'b111; {mosi_i_r0, mosi_i_r1, mosi_i_r2} <= 0; - end else begin {sclk_i_r2, sclk_i_r1, sclk_i_r0} <= {sclk_i_r1, sclk_i_r0, sclk_i}; {cs_i_r0, cs_i_r1, cs_i_r2} <= {cs_i, cs_i_r0, cs_i_r1}; @@ -149,9 +160,11 @@ always @(posedge mclk_i) begin if (rst_i_r) begin - addr_rdy_r <= 0; + addr_rdy_r <= 0; + addr_rdy_r1 <= 0; // Added to sync en_o with r_w_en_o end else begin - if (dat_in_ctr_r == 24) // changed from 16. + addr_rdy_r1 <= addr_rdy_r; + if (dat_in_ctr_r == 24) // Changed from 16. addr_rdy_r <= 1; else addr_rdy_r <= 0; end @@ -198,7 +211,7 @@ always @(posedge mclk_i) begin if (rst_i_r) en_o <= 0; else begin - en_o <= (|adc_sel_o) & (wdata_rdy_r | (r_w_en_o & addr_rdy_r)); + en_o <= ((!poll_adc_sel_en_r) & ((|adc_sel_o) & (wdata_rdy_r | (r_w_en_o & addr_rdy_r1)))); // Bit18 disables spi_s_state end end @@ -252,12 +265,13 @@ end end - always @(posedge mclk_i) begin // Test only logic to verify total number of clock cycles. NC - if (rst_i_r | poll_dat_bits_ctr_r == 528) poll_dat_bits_ctr_r <= 0; - else begin - if (mode_i & neg_edge) poll_dat_bits_ctr_r <= poll_dat_bits_ctr_r + 1; - end - end + // Test only logic to verify total number of clock cycles. NC + // always @(posedge mclk_i) begin + // if (rst_i_r | poll_dat_bits_ctr_r == 528) poll_dat_bits_ctr_r <= 0; + // else begin + // if (mode_i & neg_edge) poll_dat_bits_ctr_r <= poll_dat_bits_ctr_r + 1; + // end + // end always @(posedge mclk_i) begin if (rst_i_r | dat_out_ctr_clr) dat_out_ctr <= 0; @@ -308,39 +322,10 @@ end always @(posedge mclk_i) begin - dat_out_ctr_clr <= (dat_out_ctr == data_count_max_r); - dat_out_ctr_clr_r <= dat_out_ctr_clr; - poll_dat_ctr_clr <= (poll_dat_ctr_r == 22); - end - - always @(posedge mclk_i) begin - if (rst_i_r) dat_out_dn_r <= 0; - else dat_out_dn_r <= (((!mode_i) & dat_out_ctr_clr) | (mode_i & poll_dat_ctr_clr)); - end - - reg [2:0] dat_out_dn_latch_ctr; // Added to clear latch to fix continous read. - - always @(posedge mclk_i) begin - if (rst_i_r) dat_out_dn_latch_ctr <= 0; - dat_out_dn_latch_ctr <= (dat_out_dn_latch) ? dat_out_dn_latch_ctr + 1 : 0; - end - - always @(posedge mclk_i) begin - if (rst_i_r | neg_edge | dat_out_dn_latch_ctr == 7) dat_out_dn_latch <= 0; - else if (dat_out_dn_r) dat_out_dn_latch <= 1; - end - - always @(posedge mclk_i) begin - if (rst_i_r | poll_dat_ctr_clr) poll_dat_ctr_r <= 0; - else begin - if (poll_ctr_en_w & mode_i) poll_dat_ctr_r <= poll_dat_ctr_r + 1; - end - end - - always @(posedge mclk_i) begin if (rst_i_r) dn_clr_o <= 0; else begin - dn_clr_o <= ((!mode_i & dn_i) | (mode_i & dat_out_dn_latch));//Changed from poll_dn_i -(Added multi-cycle path) for clear pulse. + // Changed from poll_dn_i -(Added multi-cycle path) for clear pulse. + dn_clr_o <= ((!mode_i & dn_i) | (mode_i & dat_out_dn_latch)); end end @@ -360,4 +345,96 @@ end end + always @(posedge mclk_i) begin + dat_out_ctr_clr <= (dat_out_ctr == data_count_max_r); + dat_out_ctr_clr_r <= dat_out_ctr_clr; + poll_dat_ctr_clr <= (poll_dat_ctr_r >= 22); + end + + always @(posedge mclk_i) begin + if (rst_i_r) dat_out_dn_r <= 0; + else dat_out_dn_r <= (((!mode_i) & dat_out_ctr_clr) | (mode_i & poll_dat_ctr_clr)); + end + + always @(posedge mclk_i) begin + if (rst_i_r) dat_out_dn_latch_ctr <= 0; + dat_out_dn_latch_ctr <= (dat_out_dn_latch) ? dat_out_dn_latch_ctr + 1 : 0; + end + + always @(posedge mclk_i) begin + if (rst_i_r | neg_edge | dat_out_dn_latch_ctr == 7) dat_out_dn_latch <= 0; + else if (dat_out_dn_r) dat_out_dn_latch <= 1; + end + + // Logic for ADC selection for polling + + always @(posedge mclk_i) begin + case (poll_adc_state) + S0: begin + poll_adc_state <= poll_adc_sel_valid_r ? S1 : S0; + adc_count <= 0; + i <= 0; + end + S1: begin + if (i < 12) begin + poll_dat_next_ctr_r[i] <= 11; // 5x11 queue + i <= i + 1; + end else begin + poll_adc_state <= S2; + i <= 0; + end + end + S2: begin + if (i < 11) begin + if (poll_adc_sel_r[i]) begin + adc_count <= adc_count + 1; + poll_dat_next_ctr_r[adc_count] <= i; + end + i <= i + 1; + end else poll_adc_state <= (poll_adc_sel_valid_r) ? S2 : S0; + end + default: poll_adc_state <= S0; + endcase + end + + always @(posedge mclk_i) begin + if (rst_i_r) // TBD: Clear after completion of packet + poll_adc_sel_en_r <= 0; + else begin + if (addr_rdy_r) poll_adc_sel_en_r <= dat_in_r1[18]; + end + end + + always @(posedge mclk_i) begin + if (addr_rdy_r1 & poll_adc_sel_en_r) begin + poll_adc_sel_valid_r <= 1; + poll_adc_sel_r <= adc_sel_o; // Clear only with a write. + end else begin + poll_adc_sel_valid_r <= 0; + end + end + + initial poll_adc_sel_r = 11'h07FF; + initial begin // POR Reset Value + for (i = 0; i < 12; i = i + 1) begin + poll_dat_next_ctr_r[i] = i; + end + end + + always @(posedge mclk_i) begin + if (rst_i_r | poll_dat_ctr_clr) begin + poll_dat_ctr_r <= {poll_dat_next_ctr_r[0], 1'b0}; + poll_dat_next_ctr_index_r <= 0; + end else begin + if (poll_ctr_en_w & mode_i) begin + if (!poll_dat_ctr_r[0]) begin + poll_dat_ctr_r <= poll_dat_ctr_r + 1; + poll_dat_next_ctr_index_r <= poll_dat_next_ctr_index_r + 1; + end else begin + poll_dat_ctr_r <= {poll_dat_next_ctr_r[poll_dat_next_ctr_index_r], 1'b0}; + end + end + end + end + endmodule
diff --git a/fpga/gonk/top.pcf b/fpga/gonk/top.pcf index 586c938..890c9e6 100644 --- a/fpga/gonk/top.pcf +++ b/fpga/gonk/top.pcf
@@ -13,6 +13,7 @@ # the License. ###IOSet List 63 +set_io test_o 39 set_io led 56 set_io ice_prog_spi_io0 67 set_io ice_prog_spi_io1 68
diff --git a/fpga/gonk/top.v b/fpga/gonk/top.v index 7e222ed..17c9834 100644 --- a/fpga/gonk/top.v +++ b/fpga/gonk/top.v
@@ -17,6 +17,7 @@ // ////////////////////////////////////////////////////////////////////////////////// module top ( + output test_o, input clk_i, input rst_i, input op_mode_i, @@ -100,8 +101,8 @@ ); wire rst_i_sync, poll_dn_w, mclk, en_w, r_w_en_w, mode_i_sync, trf_dn_w, dn_clr; - wire [ 5:0] rwaddr_w; - wire [10:0] adc_select_w; + wire [5:0] rwaddr_w; + wire [10:0] adc_select_w, poll_adc_en_w; wire [11:0] poll_dn_bus_w; wire [15:0] wdata_w; wire [23:0] vbus_1,vshunt_1,vbus_2,vshunt_2 ,vbus_3 ,vshunt_3 ,vbus_4 ,vshunt_4 ,vbus_5 ,vshunt_5 ,vbus_6 ,vshunt_6 ; @@ -110,18 +111,18 @@ // Assign ice_prog_spi_io0 = 1'bz; assigned as input. same as output hi-z. // Assign ice_prog_spi_io1 = 1'bz; - + assign test_o = sl_sclk_i_0; pll pll_inst ( .clock_in (clk_i), .clock_out(mclk) ); - assign led = count[25]; reg [25:0] count; initial count = 0; always @(posedge mclk) begin count <= count + 1; end + assign led = count[25]; spi_s_core spi_s_core_inst ( .sclk_i(sl_sclk_i_0), @@ -134,6 +135,7 @@ .en_o(en_w), .rwaddr_o(rwaddr_w), .adc_sel_o(adc_select_w), + .poll_adc_en_o(poll_adc_en_w), .wdata_o(wdata_w), .r_w_en_o(r_w_en_w), .data_valid_o(data_valid_o), @@ -142,31 +144,6 @@ .poll_dn_i(poll_dn_w), .dn_i(trf_dn_w), .dn_clr_o(dn_clr), - - // DEBUG: hard coded vbus and vshunt values - // .vbus_1(1), - // .vshunt_1(2), - // .vbus_2(3), - // .vshunt_2(4), - // .vbus_3(5), - // .vshunt_3(6), - // .vbus_4(7), - // .vshunt_4(8), - // .vbus_5(9), - // .vshunt_5(10), - // .vbus_6(11), - // .vshunt_6(12), - // .vbus_7(13), - // .vshunt_7(14), - // .vbus_8(15), - // .vshunt_8(16), - // .vbus_9(17), - // .vshunt_9(19), - // .vbus_10(20), - // .vshunt_10(21), - // .vbus_11(22), - // .vshunt_11(23) - .vbus_1(vbus_1), .vshunt_1(vshunt_1), .vbus_2(vbus_2), @@ -191,6 +168,30 @@ .vshunt_11(vshunt_11) ); + // DEBUG: hard coded vbus and vshunt values + // .vbus_1(24'h5AAAAA), + // .vshunt_1(24'h5AAAAA), + // .vbus_2(24'h5AAAAA), + // .vshunt_2(24'h5AAAAA), + // .vbus_3(24'h5AAAAA), + // .vshunt_3(24'h5AAAAA), + // .vbus_4(24'h5AAAAA), + // .vshunt_4(24'h5AAAAA), + // .vbus_5(24'h5AAAAA), + // .vshunt_5(24'h5AAAAA), + // .vbus_6(24'h5AAAAA), + // .vshunt_6(24'h5AAAAA), + // .vbus_7(24'h5AAAAA), + // .vshunt_7(24'h5AAAAA), + // .vbus_8(24'h5AAAAA), + // .vshunt_8(24'h5AAAAA), + // .vbus_9(24'h5AAAAA), + // .vshunt_9(24'h5AAAAA), + // .vbus_10(24'h5AAAAA), + // .vshunt_10(24'h5AAAAA), + // .vbus_11(24'h5AAAAA), + // .vshunt_11(24'h5AAAAA) + rst_sync rst_sync_inst ( .clk_i (mclk), @@ -214,6 +215,7 @@ .mode_i(mode_i_sync), .rwaddr_i(rwaddr_w), .adc_sel_i(adc_select_w), + .poll_adc_en_i(poll_adc_en_w), //Enable/Disable ADCs for polling. .wdata_i(wdata_w), .dn_o(trf_dn_w), .rdata_o(rdata_w),