530 lines
18 KiB
Verilog
530 lines
18 KiB
Verilog
// ***************************************************************************
|
|
// ***************************************************************************
|
|
// Copyright (C) 2023 Analog Devices, Inc. All rights reserved.
|
|
//
|
|
// In this HDL repository, there are many different and unique modules, consisting
|
|
// of various HDL (Verilog or VHDL) components. The individual modules are
|
|
// developed independently, and may be accompanied by separate and unique license
|
|
// terms.
|
|
//
|
|
// The user should read each of these license terms, and understand the
|
|
// freedoms and responsibilities that he or she has by using this source/core.
|
|
//
|
|
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
// A PARTICULAR PURPOSE.
|
|
//
|
|
// Redistribution and use of source or resulting binaries, with or without modification
|
|
// of this file, are permitted under one of the following two license terms:
|
|
//
|
|
// 1. The GNU General Public License version 2 as published by the
|
|
// Free Software Foundation, which can be found in the top level directory
|
|
// of this repository (LICENSE_GPL2), and also online at:
|
|
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
|
|
//
|
|
// OR
|
|
//
|
|
// 2. An ADI specific BSD license, which can be found in the top level directory
|
|
// of this repository (LICENSE_ADIBSD), and also on-line at:
|
|
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
|
|
// This will allow to generate bit files and not release the source code,
|
|
// as long as it attaches to an ADI device.
|
|
//
|
|
// ***************************************************************************
|
|
// ***************************************************************************
|
|
|
|
`timescale 1ns/100ps
|
|
|
|
module axi_ltc235x_cmos #(
|
|
parameter ACTIVE_LANES = 8'b1111_1111,
|
|
parameter LTC235X_FAMILY = 0,
|
|
parameter NUM_CHANNELS = 8, // 8 for 2358, 4 for 2357, 2 for 2353
|
|
parameter DATA_WIDTH = 18 // 18 or 16 based on -18/-16
|
|
) (
|
|
|
|
input rst,
|
|
input clk,
|
|
input [ 7:0] adc_enable,
|
|
input [23:0] softspan_next,
|
|
|
|
// physical interface
|
|
|
|
output scki,
|
|
output sdi,
|
|
input scko,
|
|
input [ 7:0] sdo,
|
|
input busy,
|
|
|
|
// FIFO interface
|
|
|
|
output [ 2:0] adc_ch0_id,
|
|
output [ 2:0] adc_ch1_id,
|
|
output [ 2:0] adc_ch2_id,
|
|
output [ 2:0] adc_ch3_id,
|
|
output [ 2:0] adc_ch4_id,
|
|
output [ 2:0] adc_ch5_id,
|
|
output [ 2:0] adc_ch6_id,
|
|
output [ 2:0] adc_ch7_id,
|
|
|
|
output [31:0] adc_data_0,
|
|
output [31:0] adc_data_1,
|
|
output [31:0] adc_data_2,
|
|
output [31:0] adc_data_3,
|
|
output [31:0] adc_data_4,
|
|
output [31:0] adc_data_5,
|
|
output [31:0] adc_data_6,
|
|
output [31:0] adc_data_7,
|
|
|
|
output [ 2:0] adc_softspan_0,
|
|
output [ 2:0] adc_softspan_1,
|
|
output [ 2:0] adc_softspan_2,
|
|
output [ 2:0] adc_softspan_3,
|
|
output [ 2:0] adc_softspan_4,
|
|
output [ 2:0] adc_softspan_5,
|
|
output [ 2:0] adc_softspan_6,
|
|
output [ 2:0] adc_softspan_7,
|
|
|
|
output reg adc_valid
|
|
);
|
|
|
|
localparam DW = 24; // packet size
|
|
localparam BW = DW - 1;
|
|
|
|
// internal registers
|
|
|
|
reg busy_m1;
|
|
reg busy_m2;
|
|
reg busy_m3;
|
|
|
|
reg [ 4:0] scki_counter = 5'h0;
|
|
reg [ 4:0] data_counter = 5'h0;
|
|
|
|
reg scki_i;
|
|
reg scki_d;
|
|
|
|
reg [BW:0] adc_lane_0;
|
|
reg [BW:0] adc_lane_1;
|
|
reg [BW:0] adc_lane_2;
|
|
reg [BW:0] adc_lane_3;
|
|
reg [BW:0] adc_lane_4;
|
|
reg [BW:0] adc_lane_5;
|
|
reg [BW:0] adc_lane_6;
|
|
reg [BW:0] adc_lane_7;
|
|
|
|
reg [BW:0] adc_data_init[7:0];
|
|
reg [BW:0] adc_data_store[7:0];
|
|
|
|
reg [ 2:0] lane_0_ch = 3'd0;
|
|
reg [ 2:0] lane_1_ch = 3'd0;
|
|
reg [ 2:0] lane_2_ch = 3'd0;
|
|
reg [ 2:0] lane_3_ch = 3'd0;
|
|
reg [ 2:0] lane_4_ch = 3'd0;
|
|
reg [ 2:0] lane_5_ch = 3'd0;
|
|
reg [ 2:0] lane_6_ch = 3'd0;
|
|
reg [ 2:0] lane_7_ch = 3'd0;
|
|
|
|
reg [ 3:0] adc_lane0_shift;
|
|
reg [ 3:0] adc_lane1_shift;
|
|
reg [ 3:0] adc_lane2_shift;
|
|
reg [ 3:0] adc_lane3_shift;
|
|
reg [ 3:0] adc_lane4_shift;
|
|
reg [ 3:0] adc_lane5_shift;
|
|
reg [ 3:0] adc_lane6_shift;
|
|
reg [ 3:0] adc_lane7_shift;
|
|
|
|
reg [ 3:0] adc_lane0_shift_d;
|
|
reg [ 3:0] adc_lane1_shift_d;
|
|
reg [ 3:0] adc_lane2_shift_d;
|
|
reg [ 3:0] adc_lane3_shift_d;
|
|
reg [ 3:0] adc_lane4_shift_d;
|
|
reg [ 3:0] adc_lane5_shift_d;
|
|
reg [ 3:0] adc_lane6_shift_d;
|
|
reg [ 3:0] adc_lane7_shift_d;
|
|
|
|
reg adc_valid_init;
|
|
reg adc_valid_init_d;
|
|
|
|
reg [ 7:0] ch_data_lock = 8'hff;
|
|
reg [ 7:0] ch_capture;
|
|
reg [ 7:0] ch_captured;
|
|
|
|
reg scko_d;
|
|
reg [ 7:0] sdo_d;
|
|
|
|
reg [ 4:0] sdi_index = 5'd23;
|
|
|
|
reg [23:0] softspan_next_int;
|
|
|
|
// internal wires
|
|
|
|
wire start_transfer_s;
|
|
|
|
wire scki_cnt_rst;
|
|
|
|
wire acquire_data;
|
|
|
|
wire [17:0] adc_data_raw_s [7:0];
|
|
wire [31:0] adc_data_sign_s [7:0];
|
|
wire [31:0] adc_data_zero_s [7:0];
|
|
wire [31:0] adc_data_s [7:0];
|
|
wire [ 2:0] adc_ch_id_s [7:0];
|
|
wire [ 2:0] adc_softspan_s [7:0];
|
|
|
|
always @(posedge clk) begin
|
|
if (rst == 1'b1) begin
|
|
busy_m1 <= 1'b0;
|
|
busy_m2 <= 1'b0;
|
|
end else begin
|
|
busy_m1 <= busy;
|
|
busy_m2 <= busy_m1;
|
|
busy_m3 <= busy_m2;
|
|
end
|
|
end
|
|
|
|
assign start_transfer_s = busy_m3 & ~busy_m2;
|
|
|
|
// reading clock logic
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
scki_counter <= 5'h0;
|
|
scki_i <= 1'b1;
|
|
scki_d <= 1'b0;
|
|
end else begin
|
|
scki_d <= scki_i;
|
|
if (acquire_data == 1'b0) begin
|
|
scki_counter <= 5'h0;
|
|
scki_i <= 1'b1;
|
|
end else if (scki_cnt_rst & (scki_d & ~scki_i)) begin // end of a capture
|
|
scki_counter <= 5'h1;
|
|
scki_i <= 1'b1;
|
|
end else if (scki_i == 1'b0) begin
|
|
scki_counter <= scki_counter + 5'd1;
|
|
scki_i <= 1'b1;
|
|
end else begin
|
|
scki_counter <= scki_counter;
|
|
scki_i <= ~scki_i;
|
|
end
|
|
end
|
|
end
|
|
|
|
assign scki_cnt_rst = (scki_counter == DW);
|
|
assign scki = scki_i | ~acquire_data;
|
|
|
|
/*
|
|
The device sends each channel data on one of the 8 lines.
|
|
Data is stored in the device in a ring buffer. After the first packet is read
|
|
and no new conversion is requested if the reading process is restarted,
|
|
the new data on the lines will be from the next index from the ring buffer.
|
|
e.g For second read process without a conversion start
|
|
line 0 = channel 1, line 1 = channel 2, line 2 = channel 3; so on and so forth.
|
|
|
|
The ring buffer contains the crc data on the 8(last position.)
|
|
e.g for a 4'th reading cycle:
|
|
line 0 = ch 3
|
|
line 1 = ch 4
|
|
line 2 = ch 5
|
|
line 3 = ch 6
|
|
line 4 = ch 7
|
|
line 5 = crc
|
|
line 6 = ch 0
|
|
line 7 = ch 1
|
|
|
|
Because there is no rule for a specific number of lanes to be enabled at a given time
|
|
the interface can handle every combination of enabled lanes with enabled channels.
|
|
The valid signal will only be asserted after all enabled channels are stored.
|
|
This means that the user must adjust the sampling frequency based on the
|
|
interface clock frequency and the maximum position/index
|
|
difference +1 of a channel data and the first enabled lane that will
|
|
pass that channels data, maximum difference is 8(e.g line 0 to line 7).
|
|
e.g. If only lanes 1 and 2(0 to 7) are enabled,
|
|
1. The user wants to capture the 6'th(0 to 7) channel, 5 reading cycles are required.
|
|
2. The user wants to capture channel 0, 8 reading cycles are required.
|
|
*/
|
|
|
|
// capture data per lane in rx buffers adc_lane_X on every edge of scko
|
|
// ignore when busy forced scko to 0
|
|
always @(posedge clk) begin
|
|
scko_d <= scko;
|
|
sdo_d <= sdo;
|
|
if (scko != scko_d && scki != scki_d) begin
|
|
adc_lane_0 <= {adc_lane_0[BW-1:0], sdo_d[0]};
|
|
adc_lane_1 <= {adc_lane_1[BW-1:0], sdo_d[1]};
|
|
adc_lane_2 <= {adc_lane_2[BW-1:0], sdo_d[2]};
|
|
adc_lane_3 <= {adc_lane_3[BW-1:0], sdo_d[3]};
|
|
adc_lane_4 <= {adc_lane_4[BW-1:0], sdo_d[4]};
|
|
adc_lane_5 <= {adc_lane_5[BW-1:0], sdo_d[5]};
|
|
adc_lane_6 <= {adc_lane_6[BW-1:0], sdo_d[6]};
|
|
adc_lane_7 <= {adc_lane_7[BW-1:0], sdo_d[7]};
|
|
end
|
|
end
|
|
|
|
// store the data from the rx buffers when all bits are received
|
|
// when data transaction window is done
|
|
// index is based by lane
|
|
always @(posedge clk) begin
|
|
if (rst == 1'b1) begin
|
|
adc_data_init[0] <= 'h0;
|
|
adc_data_init[1] <= 'h0;
|
|
adc_data_init[2] <= 'h0;
|
|
adc_data_init[3] <= 'h0;
|
|
adc_data_init[4] <= 'h0;
|
|
adc_data_init[5] <= 'h0;
|
|
adc_data_init[6] <= 'h0;
|
|
adc_data_init[7] <= 'h0;
|
|
data_counter <= 5'h0;
|
|
end else begin
|
|
data_counter <= scki_counter;
|
|
if (data_counter == DW) begin
|
|
adc_data_init[0] <= adc_lane_0;
|
|
adc_data_init[1] <= adc_lane_1;
|
|
adc_data_init[2] <= adc_lane_2;
|
|
adc_data_init[3] <= adc_lane_3;
|
|
adc_data_init[4] <= adc_lane_4;
|
|
adc_data_init[5] <= adc_lane_5;
|
|
adc_data_init[6] <= adc_lane_6;
|
|
adc_data_init[7] <= adc_lane_7;
|
|
end
|
|
end
|
|
end
|
|
|
|
// lane_x_ch - channel corresponds to which lane, e.g. lane_0_ch stores the current channel lane 0 has
|
|
// ch_data_lock[i] - locks ch i, e.g. ch_data_lock[7] = 1 means data from channel 7 has already been sent to an active lane, channel 7 should now be locked
|
|
// dont acquire data if all channels are all already locked
|
|
always @(posedge clk) begin
|
|
if (start_transfer_s) begin
|
|
lane_0_ch <= 3'd0;
|
|
lane_1_ch <= 3'd1;
|
|
lane_2_ch <= 3'd2;
|
|
lane_3_ch <= 3'd3;
|
|
lane_4_ch <= 3'd4;
|
|
lane_5_ch <= 3'd5;
|
|
lane_6_ch <= 3'd6;
|
|
lane_7_ch <= 3'd7;
|
|
ch_data_lock <= 8'd0;
|
|
end else if (acquire_data == 1'b1 && (scki_cnt_rst & (~scki_d & scki_i))) begin
|
|
lane_0_ch <= lane_0_ch + 3'd1;
|
|
lane_1_ch <= lane_1_ch + 3'd1;
|
|
lane_2_ch <= lane_2_ch + 3'd1;
|
|
lane_3_ch <= lane_3_ch + 3'd1;
|
|
lane_4_ch <= lane_4_ch + 3'd1;
|
|
lane_5_ch <= lane_5_ch + 3'd1;
|
|
lane_6_ch <= lane_6_ch + 3'd1;
|
|
lane_7_ch <= lane_7_ch + 3'd1;
|
|
ch_data_lock[lane_0_ch] <= ACTIVE_LANES[0] ? 1'b1 : ch_data_lock[lane_0_ch];
|
|
ch_data_lock[lane_1_ch] <= ACTIVE_LANES[1] ? 1'b1 : ch_data_lock[lane_1_ch];
|
|
ch_data_lock[lane_2_ch] <= ACTIVE_LANES[2] ? 1'b1 : ch_data_lock[lane_2_ch];
|
|
ch_data_lock[lane_3_ch] <= ACTIVE_LANES[3] ? 1'b1 : ch_data_lock[lane_3_ch];
|
|
ch_data_lock[lane_4_ch] <= ACTIVE_LANES[4] ? 1'b1 : ch_data_lock[lane_4_ch];
|
|
ch_data_lock[lane_5_ch] <= ACTIVE_LANES[5] ? 1'b1 : ch_data_lock[lane_5_ch];
|
|
ch_data_lock[lane_6_ch] <= ACTIVE_LANES[6] ? 1'b1 : ch_data_lock[lane_6_ch];
|
|
ch_data_lock[lane_7_ch] <= ACTIVE_LANES[7] ? 1'b1 : ch_data_lock[lane_7_ch];
|
|
end
|
|
end
|
|
|
|
assign acquire_data = ~((ch_data_lock[0] | ~adc_enable[0]) &
|
|
(ch_data_lock[1] | ~adc_enable[1]) &
|
|
(ch_data_lock[2] | ~adc_enable[2]) &
|
|
(ch_data_lock[3] | ~adc_enable[3]) &
|
|
(ch_data_lock[4] | ~adc_enable[4]) &
|
|
(ch_data_lock[5] | ~adc_enable[5]) &
|
|
(ch_data_lock[6] | ~adc_enable[6]) &
|
|
(ch_data_lock[7] | ~adc_enable[7]));
|
|
|
|
// hold lane status and lane channel
|
|
// for datasyncing with valid signal
|
|
always @(posedge clk) begin
|
|
if (rst == 1'b1 || adc_valid == 1'b1) begin
|
|
adc_lane0_shift <= 4'd0;
|
|
adc_lane1_shift <= 4'd0;
|
|
adc_lane2_shift <= 4'd0;
|
|
adc_lane3_shift <= 4'd0;
|
|
adc_lane4_shift <= 4'd0;
|
|
adc_lane5_shift <= 4'd0;
|
|
adc_lane6_shift <= 4'd0;
|
|
adc_lane7_shift <= 4'd0;
|
|
adc_lane0_shift_d <= 4'd0;
|
|
adc_lane1_shift_d <= 4'd0;
|
|
adc_lane2_shift_d <= 4'd0;
|
|
adc_lane3_shift_d <= 4'd0;
|
|
adc_lane4_shift_d <= 4'd0;
|
|
adc_lane5_shift_d <= 4'd0;
|
|
adc_lane6_shift_d <= 4'd0;
|
|
adc_lane7_shift_d <= 4'd0;
|
|
end else begin
|
|
adc_lane0_shift <= {ACTIVE_LANES[0], lane_0_ch};
|
|
adc_lane1_shift <= {ACTIVE_LANES[1], lane_1_ch};
|
|
adc_lane2_shift <= {ACTIVE_LANES[2], lane_2_ch};
|
|
adc_lane3_shift <= {ACTIVE_LANES[3], lane_3_ch};
|
|
adc_lane4_shift <= {ACTIVE_LANES[4], lane_4_ch};
|
|
adc_lane5_shift <= {ACTIVE_LANES[5], lane_5_ch};
|
|
adc_lane6_shift <= {ACTIVE_LANES[6], lane_6_ch};
|
|
adc_lane7_shift <= {ACTIVE_LANES[7], lane_7_ch};
|
|
adc_lane0_shift_d <= adc_lane0_shift;
|
|
adc_lane1_shift_d <= adc_lane1_shift;
|
|
adc_lane2_shift_d <= adc_lane2_shift;
|
|
adc_lane3_shift_d <= adc_lane3_shift;
|
|
adc_lane4_shift_d <= adc_lane4_shift;
|
|
adc_lane5_shift_d <= adc_lane5_shift;
|
|
adc_lane6_shift_d <= adc_lane6_shift;
|
|
adc_lane7_shift_d <= adc_lane7_shift;
|
|
end
|
|
end
|
|
|
|
// stores the data from the rx buffer, but now based on ch
|
|
// index is based on ch, not lane anymore
|
|
always @(posedge clk) begin
|
|
if (rst == 1'b1) begin
|
|
adc_data_store[0] <= 'd0;
|
|
adc_data_store[1] <= 'd0;
|
|
adc_data_store[2] <= 'd0;
|
|
adc_data_store[3] <= 'd0;
|
|
adc_data_store[4] <= 'd0;
|
|
adc_data_store[5] <= 'd0;
|
|
adc_data_store[6] <= 'd0;
|
|
adc_data_store[7] <= 'd0;
|
|
end else begin
|
|
if (!adc_valid_init_d & adc_valid_init) begin
|
|
if (adc_lane0_shift_d[3] == 1'b1) begin
|
|
adc_data_store[adc_lane0_shift_d[2:0]] <= adc_data_init[0];
|
|
end
|
|
if (adc_lane1_shift_d[3] == 1'b1) begin
|
|
adc_data_store[adc_lane1_shift_d[2:0]] <= adc_data_init[1];
|
|
end
|
|
if (adc_lane2_shift_d[3] == 1'b1) begin
|
|
adc_data_store[adc_lane2_shift_d[2:0]] <= adc_data_init[2];
|
|
end
|
|
if (adc_lane3_shift_d[3] == 1'b1) begin
|
|
adc_data_store[adc_lane3_shift_d[2:0]] <= adc_data_init[3];
|
|
end
|
|
if (adc_lane4_shift_d[3] == 1'b1) begin
|
|
adc_data_store[adc_lane4_shift_d[2:0]] <= adc_data_init[4];
|
|
end
|
|
if (adc_lane5_shift_d[3] == 1'b1) begin
|
|
adc_data_store[adc_lane5_shift_d[2:0]] <= adc_data_init[5];
|
|
end
|
|
if (adc_lane6_shift_d[3] == 1'b1) begin
|
|
adc_data_store[adc_lane6_shift_d[2:0]] <= adc_data_init[6];
|
|
end
|
|
if (adc_lane7_shift_d[3] == 1'b1) begin
|
|
adc_data_store[adc_lane7_shift_d[2:0]] <= adc_data_init[7];
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
// extract info from the data bits
|
|
genvar i;
|
|
generate
|
|
for (i=0; i < 8; i=i+1) begin: format
|
|
assign adc_data_raw_s[i] = adc_data_store[i][BW:DW-DATA_WIDTH];
|
|
assign adc_data_sign_s[i] = {{(32-DATA_WIDTH){adc_data_raw_s[i][DATA_WIDTH-1]}}, adc_data_raw_s[i]};
|
|
assign adc_data_zero_s[i] = {{(32-DATA_WIDTH){1'b0}}, adc_data_raw_s[i]};
|
|
assign adc_data_s[i] = (adc_softspan_s[i] == 3'b0)? 32'h0 :
|
|
(adc_softspan_s[i][1])? adc_data_sign_s[i] :
|
|
adc_data_zero_s[i] ;
|
|
if (NUM_CHANNELS == 8) begin
|
|
assign adc_ch_id_s[i] = adc_data_store[i][5:3];
|
|
end else if (NUM_CHANNELS == 4) begin
|
|
assign adc_ch_id_s[i] = {1'b0, adc_data_store[i][4:3]};
|
|
end else begin
|
|
assign adc_ch_id_s[i] = {2'b0, adc_data_store[i][3]};
|
|
end
|
|
assign adc_softspan_s[i] = adc_data_store[i][2:0];
|
|
end
|
|
endgenerate
|
|
|
|
// assign extracted adc data to corresponding outputs
|
|
assign adc_data_0 = adc_data_s[0];
|
|
assign adc_data_1 = adc_data_s[1];
|
|
assign adc_data_2 = adc_data_s[2];
|
|
assign adc_data_3 = adc_data_s[3];
|
|
assign adc_data_4 = adc_data_s[4];
|
|
assign adc_data_5 = adc_data_s[5];
|
|
assign adc_data_6 = adc_data_s[6];
|
|
assign adc_data_7 = adc_data_s[7];
|
|
|
|
// assign extracted adc channel id to corresponding outputs
|
|
assign adc_ch0_id = adc_ch_id_s[0];
|
|
assign adc_ch1_id = adc_ch_id_s[1];
|
|
assign adc_ch2_id = adc_ch_id_s[2];
|
|
assign adc_ch3_id = adc_ch_id_s[3];
|
|
assign adc_ch4_id = adc_ch_id_s[4];
|
|
assign adc_ch5_id = adc_ch_id_s[5];
|
|
assign adc_ch6_id = adc_ch_id_s[6];
|
|
assign adc_ch7_id = adc_ch_id_s[7];
|
|
|
|
// assign extracted adc channel id to corresponding outputs
|
|
assign adc_softspan_0 = adc_softspan_s[0];
|
|
assign adc_softspan_1 = adc_softspan_s[1];
|
|
assign adc_softspan_2 = adc_softspan_s[2];
|
|
assign adc_softspan_3 = adc_softspan_s[3];
|
|
assign adc_softspan_4 = adc_softspan_s[4];
|
|
assign adc_softspan_5 = adc_softspan_s[5];
|
|
assign adc_softspan_6 = adc_softspan_s[6];
|
|
assign adc_softspan_7 = adc_softspan_s[7];
|
|
|
|
// initial valid signal
|
|
always @(posedge clk) begin
|
|
if (rst == 1'b1) begin
|
|
adc_valid_init <= 1'b0;
|
|
end else begin
|
|
if (data_counter == DW && adc_valid_init == 1'b0) begin
|
|
adc_valid_init <= 1'b1;
|
|
end else begin
|
|
adc_valid_init <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
|
|
// delayed both valid signal and data_lock signal
|
|
// for datasyncing with valid signal
|
|
always @(posedge clk) begin
|
|
if (rst == 1'b1 || adc_valid == 1'b1) begin
|
|
adc_valid <= 1'b0;
|
|
adc_valid_init_d <= 1'b0;
|
|
ch_capture <= 8'd0;
|
|
ch_captured <= 8'd0;
|
|
end else begin
|
|
ch_capture <= ch_data_lock;
|
|
ch_captured <= ch_capture;
|
|
adc_valid_init_d <= adc_valid_init;
|
|
adc_valid <= adc_valid_init_d &
|
|
(ch_captured[0] | ~adc_enable[0]) &
|
|
(ch_captured[1] | ~adc_enable[1]) &
|
|
(ch_captured[2] | ~adc_enable[2]) &
|
|
(ch_captured[3] | ~adc_enable[3]) &
|
|
(ch_captured[4] | ~adc_enable[4]) &
|
|
(ch_captured[5] | ~adc_enable[5]) &
|
|
(ch_captured[6] | ~adc_enable[6]) &
|
|
(ch_captured[7] | ~adc_enable[7]);
|
|
end
|
|
end
|
|
|
|
// every negedge of scki, update index of sdi
|
|
always @(posedge clk) begin
|
|
if (start_transfer_s || rst) begin
|
|
sdi_index <= 5'd23;
|
|
end else begin
|
|
if (scki && !scki_d && sdi_index != 5'b11111) begin
|
|
sdi_index <= sdi_index - 5'b1;
|
|
end
|
|
end
|
|
end
|
|
|
|
// update next softspan configuration every after busy
|
|
always @(posedge clk) begin
|
|
if (rst == 1'b1) begin
|
|
softspan_next_int <= 24'hff_ffff;
|
|
end else begin
|
|
if (busy_m3 & ~busy_m2) begin
|
|
softspan_next_int <= softspan_next;
|
|
end else begin
|
|
softspan_next_int <= softspan_next_int;
|
|
end
|
|
end
|
|
end
|
|
|
|
assign sdi = (sdi_index != 5'b11111)? softspan_next_int[sdi_index] : 1'b0;
|
|
|
|
endmodule
|