sync chunk 11/12

This commit is contained in:
chunk-sync
2026-09-11 16:18:36 +08:00
parent c315cef09e
commit c2c1bb2648
922 changed files with 102283 additions and 6793 deletions
@@ -0,0 +1,130 @@
`timescale 1 ns / 1 ps
module acq_collect#
(
parameter CLK_PERIOD = 10 ,
parameter SPI_QTY = 4 ,
parameter CH_OF_SPI = 16
)
(
input clk ,
input rst_n ,
input [24*SPI_QTY-1:0] s_axis_tdata_array ,
input [ SPI_QTY-1:0] s_axis_tlast_array ,
input [ SPI_QTY-1:0] s_axis_tvalid_array ,
(*mark_debug="true"*)output reg [24-1:0] m_axis_tdata ,
(*mark_debug="true"*)output reg m_axis_tlast ,
(*mark_debug="true"*)output reg m_axis_tvalid
);
//*****************************************************************************
// localparam definition
//*****************************************************************************
localparam IDLE = 4'd0 ;
localparam SCAN_ST = 4'd1 ;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
reg [ 4-1:0] cstate ;
reg [ 4-1:0] nstate ;
wire [24-1:0] s_axis_tdata[SPI_QTY-1:0] ;
wire s_axis_tlast[SPI_QTY-1:0] ;
wire s_axis_tvalid[SPI_QTY-1:0] ;
reg [24-1:0] s_axis_tdata_r[SPI_QTY-1:0] ;
reg s_axis_tlast_r[SPI_QTY-1:0] ;
reg s_axis_tvalid_r[SPI_QTY-1:0] ;
(*mark_debug="true"*)reg [ 8-1:0] scan_cnt ;
genvar i;
//*****************************************************************************
generate
for(i=0;i<SPI_QTY;i=i+1) begin : rx_data
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
s_axis_tdata_r[i] <= 0;
s_axis_tvalid_r[i] <= 1'b0;
s_axis_tlast_r[i] <= 1'b0;
end else if ( s_axis_tvalid[i] ) begin
s_axis_tdata_r[i] <= s_axis_tdata[i];
s_axis_tvalid_r[i] <= s_axis_tvalid[i];
s_axis_tlast_r[i] <= s_axis_tlast[i];
end
end
end
endgenerate
always@( posedge clk or negedge rst_n ) begin
if( !rst_n ) cstate <= IDLE;
else cstate <= nstate;
end
always@( * ) begin
case ( cstate )
IDLE:
if ( s_axis_tvalid_array )
nstate <= SCAN_ST;
else
nstate <= IDLE;
SCAN_ST:
if ( scan_cnt == SPI_QTY-1 )
nstate <= IDLE;
else
nstate <= SCAN_ST;
default:
nstate <= IDLE;
endcase
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
scan_cnt <= 0;
else if ( cstate == IDLE )
scan_cnt <= 0;
else if ( cstate == SCAN_ST )
scan_cnt <= scan_cnt + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
m_axis_tvalid <= 1'b0;
m_axis_tdata <= 0;
end else if ( cstate == SCAN_ST ) begin
m_axis_tvalid <= s_axis_tvalid_r[scan_cnt];
m_axis_tdata <= s_axis_tdata_r[scan_cnt];
end else begin
m_axis_tvalid <= 1'b0;
end
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
m_axis_tlast <= 1'b0;
end else if ( cstate == SCAN_ST && scan_cnt == SPI_QTY-1 ) begin
m_axis_tlast <= s_axis_tlast_r[SPI_QTY-1];
end else begin
m_axis_tlast <= 1'b0;
end
end
//*****************************************************************************
// Wire assignment
//*****************************************************************************
generate
for(i=0;i<SPI_QTY;i=i+1) begin : unpack_res
assign s_axis_tdata[i][23:16] = s_axis_tdata_array[24*i+23 : 24*i+16] + CH_OF_SPI*i;
assign s_axis_tdata[i][15: 0] = s_axis_tdata_array[24*i+15 : 24*i+ 0];
assign s_axis_tlast[i] = s_axis_tlast_array[i];
assign s_axis_tvalid[i] = s_axis_tvalid_array[i];
end
endgenerate
endmodule
@@ -0,0 +1,124 @@
`timescale 1 ns / 1 ps
module ad7689_dual_ctrl#
(
parameter CLK_PERIOD = 10
)
(
input clk ,
input rst_n ,
input enable ,
(*mark_debug="true"*)output cnv_start ,//[ 2-1:0]
(*mark_debug="true"*)output acq_start //[ 2-1:0]
);
//*****************************************************************************
// localparam definition
//*****************************************************************************
localparam T_CYC = 1000000/CLK_PERIOD; //every channel is 50kHz(400kHz/8)///1kHz(8kHz/8)
localparam T_CYC_HALF = T_CYC/2 ;
localparam T_DEAD = 2500/CLK_PERIOD ;//50/CLK_PERIOD 2500/CLK_PERIOD
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
reg [32-1:0] clk_cnt ;
reg square ;
reg square_r ;
reg [ 8-1:0] dead_cnt ;
reg a_cnv_start ;
reg a_acq_start ;
// reg b_cnv_start ;
// reg b_acq_start ;
//*****************************************************************************
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
clk_cnt <= 0;
else if ( !enable )
clk_cnt <= 0;
else if ( clk_cnt == T_CYC - 1 )
clk_cnt <= 0;
else
clk_cnt <= clk_cnt + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
square <= 0;
else if ( clk_cnt == T_CYC - 1 )
square <= 1'b1;
else if ( clk_cnt == T_CYC_HALF - 1 )
square <= 0;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
square_r <= 0;
else
square_r <= square;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
a_cnv_start <= 1'b0;
else if ( square && !square_r )
a_cnv_start <= 1'b1;
else
a_cnv_start <= 1'b0;
end
// always @ ( posedge clk or negedge rst_n ) begin
// if( !rst_n )
// b_cnv_start <= 1'b0;
// else if ( !square && square_r )
// b_cnv_start <= 1'b1;
// else
// b_cnv_start <= 1'b0;
// end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
dead_cnt <= T_DEAD;
else if ( square != square_r )
dead_cnt <= 0;
else if ( dead_cnt != T_DEAD )
dead_cnt <= dead_cnt + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
a_acq_start <= 1'b0;
else if ( !square && dead_cnt == T_DEAD - 1 )
a_acq_start <= 1'b1;
else
a_acq_start <= 1'b0;
end
// always @ ( posedge clk or negedge rst_n ) begin
// if( !rst_n )
// b_acq_start <= 1'b0;
// else if ( square && dead_cnt == T_DEAD - 1 )
// b_acq_start <= 1'b1;
// else
// b_acq_start <= 1'b0;
// end
//*****************************************************************************
// Wire assignment
//*****************************************************************************
assign cnv_start = a_cnv_start;
assign acq_start = a_acq_start;
// assign cnv_start[0] = a_cnv_start;
// assign cnv_start[1] = b_cnv_start;
// assign acq_start[0] = a_acq_start;
// assign acq_start[1] = b_acq_start;
endmodule
@@ -0,0 +1,265 @@
`timescale 1 ns / 1 ps
module ad7689_dual_if#
(
parameter CLK_PERIOD = 10
)
(
input clk ,
input rst_n ,
input enable ,
input cnv_start ,
input acq_start ,
//------------------------------------------ acquisition stream
(*mark_debug="true"*)output reg [24-1:0] m_axis_acq_tdata ,
(*mark_debug="true"*)output reg m_axis_acq_tlast ,
(*mark_debug="true"*)output reg m_axis_acq_tvalid ,
//------------------------------------------ device spi
(*mark_debug="true"*)output reg cnv ,
(*mark_debug="true"*)output reg sck ,
(*mark_debug="true"*)output mosi ,
(*mark_debug="true"*)input miso
);
//*****************************************************************************
// localparam definition
//*****************************************************************************
localparam DATA_WIDTH = 16 ;
localparam CLK_DIV = 6 ;
localparam CNT_POS = 0 ;
localparam CNT_NEG = CLK_DIV/2 ;
localparam T_SCCS = 2000/CLK_PERIOD ;
localparam T_SCH = 600/CLK_PERIOD ;
localparam IDLE = 4'd0;
localparam TRANS_ST = 4'd1;
localparam END_ST = 4'd2;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
reg [ 4-1:0] cstate ;
reg [ 4-1:0] nstate ;
reg clk_en ;
reg [ 9-1:0] clk_cnt ;
reg sck_pos ;
reg sck_neg ;
reg [ 8-1:0] trans_cnt ;
(*mark_debug="true"*)reg acq ;//[ 2-1:0]
(*mark_debug="true"*)reg [ 3-1:0] cnv_channel ;
reg [ 3-1:0] acq_channel ;
wire [ 14-1:0] cfg_reg ;
(*mark_debug="true"*)reg [ 4-1:0] cfg_bits ;
(*mark_debug="true"*)reg [DATA_WIDTH-1:0] rx_data ;
(*mark_debug="true"*)reg rx_data_en ;
wire [ 8-1:0] channel ;
genvar i;
//*****************************************************************************
// generate
// for(i=0; i<2; i=i+1) begin : cnv_ctrl
// always @ ( posedge clk or negedge rst_n ) begin
// if ( !rst_n )
// cnv[i] <= 1'b1;
// else if ( cnv_start[i] )
// cnv[i] <= 1'b1;
// else if ( acq_start[i] )
// cnv[i] <= 1'b0;
// end
// end
// endgenerate
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
cnv <= 1'b1;
else if ( cnv_start )
cnv <= 1'b1;
else if ( acq_start )
cnv <= 1'b0;
end
// generate
// for(i=0; i<2; i=i+1) begin : acq_ctrl
// always @ ( posedge clk or negedge rst_n ) begin
// if ( !rst_n )
// acq[i] <= 1'b0;
// else if ( acq_start[i] )
// acq[i] <= 1'b1;
// else if ( cnv_start[i] )
// acq[i] <= 1'b0;
// end
// end
// endgenerate
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
acq <= 1'b0;
else if ( acq_start )
acq <= 1'b1;
else if ( cnv_start )
acq <= 1'b0;
end
always@( posedge clk or negedge rst_n ) begin
if( !rst_n ) cstate <= IDLE;
else cstate <= nstate;
end
always@( * ) begin
case ( cstate )
IDLE:
if ( acq_start )
nstate <= TRANS_ST;
else
nstate <= IDLE;
TRANS_ST:
if( trans_cnt == DATA_WIDTH )
nstate <= END_ST;
else
nstate <= TRANS_ST;
END_ST:
nstate <= IDLE;
default:
nstate <= IDLE;
endcase
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
clk_en <= 0;
else if ( cstate == IDLE && nstate == TRANS_ST )
clk_en <= 1'b1;
else if ( cstate == END_ST )
clk_en <= 1'b0;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
clk_cnt <= 0;
else if ( !clk_en || clk_cnt == CLK_DIV-1 )
clk_cnt <= 0;
else
clk_cnt <= clk_cnt + 1;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
sck_pos <= 0;
else if ( clk_en && (clk_cnt == CNT_POS) )
sck_pos <= 1;
else
sck_pos <= 0;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
sck_neg <= 0;
else if ( clk_en && (clk_cnt == CNT_NEG) )
sck_neg <= 1;
else
sck_neg <= 0;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
sck <= 0;
else if ( sck_pos && nstate == TRANS_ST )
sck <= 1'b1;
else if ( sck_neg )
sck <= 1'b0;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
trans_cnt <= 0;
else if ( cstate == IDLE )
trans_cnt <= 0;
else if ( sck_neg )
trans_cnt <= trans_cnt + 1'b1;
end
//conv/acq channel
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
cnv_channel <= 3'd0;
else if ( cnv_start )//cnv_start[1]
cnv_channel <= cnv_channel + 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
acq_channel <= 3'd0;
else if ( cnv_start )//cnv_start[1]
acq_channel <= cnv_channel;
end
//read/write after conversion (RAC)
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
cfg_bits <= 14'd13;
else if ( acq_start )
cfg_bits <= 14'd13;
else if ( sck_neg && cfg_bits != 0 )
cfg_bits <= cfg_bits - 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
rx_data <= 0;
else if ( sck_neg )
rx_data <= {rx_data[DATA_WIDTH-2:0], miso};
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
rx_data_en <= 1'b0;
else if ( sck_neg && trans_cnt == DATA_WIDTH - 1 )
rx_data_en <= 1'b1;
else
rx_data_en <= 1'b0;
end
//send
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
m_axis_acq_tdata <= 0;
m_axis_acq_tvalid <= 1'b0;
end else if ( rx_data_en ) begin
m_axis_acq_tdata <= {channel, rx_data};
m_axis_acq_tvalid <= 1'b1;
end else
m_axis_acq_tvalid <= 1'b0;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
m_axis_acq_tlast <= 1'b0;
else if ( rx_data_en && acq_channel == 7 && acq )
m_axis_acq_tlast <= 1'b1;
else
m_axis_acq_tlast <= 1'b0;
end
//*****************************************************************************
// Wire assignment
//*****************************************************************************
// assign cfg_reg = {cfg[13:10], cnv_channel, cfg[6:0]};
assign cfg_reg = {1'b1, 3'b010, cnv_channel, 1'b1, 3'b000, 2'b00, 1'b1};
assign mosi = cfg_reg[cfg_bits];
// assign channel = {acq_channel, acq[1]};
assign channel = acq_channel ;//acq[0]? acq_channel:(acq_channel + 8'd8);
endmodule
@@ -0,0 +1,106 @@
`timescale 1ns/1ps
module ad7689_dual_if_tb();
//*****************************************************************************
// Parameter definition
//*****************************************************************************
localparam T_CLK = 10 ; //ns
localparam DATA_WIDTH = 64 ;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
reg clk ;
reg rst_n ;
reg enable ;
wire [ 2-1:0] cnv_start ;
wire [ 2-1:0] acq_start ;
wire [ 2-1:0] cnv ;
wire sck ;
wire mosi ;
wire miso ;
//*****************************************************************************
// Wire assignment
//*****************************************************************************
always #( T_CLK/2.0 ) clk = !clk;
initial begin
Initial();
#100 rst_n = 0;
#100 rst_n = 1;
enable = 1'b1;
end
//*****************************************************************************
// Task
//*****************************************************************************
task Initial;
begin
clk <= 1'b0 ;
rst_n <= 1'b0 ;
enable <= 1'b0 ;
end
endtask
//*****************************************************************************
// Instantiation
//*****************************************************************************
ad7689_dual_ctrl#
(
.CLK_PERIOD ( 10 )
)
u_ad7689_dual_ctrl
(
.clk ( clk ),
.rst_n ( rst_n ),
.enable ( enable ),
.cnv_start ( cnv_start ),
.acq_start ( acq_start )
);
ad7689_dual_if#
(
.CLK_PERIOD ( 10 )
)
DUT
(
.clk ( clk ),
.rst_n ( rst_n ),
.enable ( enable ),
.cnv_start ( cnv_start ),
.acq_start ( acq_start ),
.cnv ( cnv ),
.sck ( sck ),
.mosi ( mosi ),
.miso ( miso )
);
ad7689_mod u_ad7689_mod_0
(
.cnv ( cnv[0] ),
.sck ( sck ),
.mosi ( mosi ),
.miso ( miso )
);
ad7689_mod u_ad7689_mod_1
(
.cnv ( cnv[1] ),
.sck ( sck ),
.mosi ( mosi ),
.miso ( miso )
);
endmodule
@@ -0,0 +1,62 @@
`timescale 1ns/1ps
module ad7689_mod#
(
parameter DATA_WIDTH = 16
)
(
input [16-1:0] init_data ,
input cnv ,
input sck ,
input mosi ,
inout miso
);
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
reg rst_n ;
reg [16 - 1:0] acq_data ;
// reg [16 - 1:0] acq_data_r ;
reg [ 4 - 1:0] n ;
//*****************************************************************************
initial begin
#100 rst_n = 0;
#50 rst_n = 1;
end
always @ ( negedge rst_n or posedge cnv ) begin
if( !rst_n )
acq_data <= init_data;
else if( cnv )
acq_data <= acq_data + 1'b1;
end
// always @ ( negedge rst_n or negedge cnv ) begin
// if( !rst_n )
// acq_data_r <= init_data;
// else if( ~cnv )
// acq_data_r <= acq_data;
// end
always @ ( negedge sck or negedge rst_n or posedge cnv ) begin
if( !rst_n )
n <= 15;
else if( cnv )
n <= 15;
else
n <= n - 1'b1;
end
//*****************************************************************************
// Wire assignment
//*****************************************************************************
assign miso = (cnv)? 1'bZ:acq_data[n];
endmodule
@@ -0,0 +1,70 @@
`timescale 1 ns / 1 ps
module cur_ch_map#
(
parameter CLK_PERIOD = 10 ,
parameter CH_QTY = 64
)
(
input clk ,
input rst_n ,
input [ 8*CH_QTY-1:0] ch_map_array ,
//------------------------------------------ PL logic
input [24-1:0] s_axis_tdata ,
input s_axis_tlast ,
input s_axis_tvalid ,
//------------------------------------------ PC logic
(*mark_debug="true"*)output cur_array_update ,
output [16*CH_QTY-1:0] cur_array
);
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
wire [ 8-1:0] ch_map2pc[0:CH_QTY-1] ;
(*mark_debug="true"*)wire [ 8-1:0] ch_pl ;
(*mark_debug="true"*)wire [ 8-1:0] ch_pc ;
reg [16-1:0] current[0:CH_QTY-1] ;
(*mark_debug="true"*)reg current_update ;
integer i;
genvar j;
//*****************************************************************************
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
current_update <= 1'b0;
for (i=0; i<CH_QTY; i=i+1) begin
current[i] <= 0;
end
end else if ( s_axis_tvalid ) begin
current_update <= s_axis_tlast;
current[ch_pc] <= s_axis_tdata[15:0];
end else
current_update <= 1'b0;
end
//*****************************************************************************
// Wire assignment
//*****************************************************************************
assign ch_pl = s_axis_tdata[23:16];
assign ch_pc = ch_map2pc[ch_pl];
generate
for(j=0;j<CH_QTY;j=j+1) begin : unpack
assign ch_map2pc[j] = ch_map_array[8*j+7 : 8*j];
end
endgenerate
generate
for(j=0;j<CH_QTY;j=j+1) begin : pack
assign cur_array[16*j+15 : 16*j] = current[j];
end
endgenerate
assign cur_array_update = current_update;
endmodule
@@ -0,0 +1,306 @@
`timescale 1 ns / 1 ps
module cur_mon_config#
(
parameter CH_QTY = 64
)
(
input clk ,
input rst_n ,
input [13-1:0] bram_addr ,
input bram_clk ,
input [32-1:0] bram_din ,
output reg [32-1:0] bram_dout ,
input bram_en ,
input bram_rst ,
input [ 4-1:0] bram_we ,
output reg clear_int ,
output [ 8*CH_QTY-1:0] ch_map_array ,
output reg [14-1:0] cfg_reg ,
(*mark_debug="true"*)output reg cnv_en ,
output reg [32-1:0] cnv_period_us ,
output [16*CH_QTY-1:0] thr_ch_cur_array ,
(*mark_debug="true"*)output reg [32-1:0] thr_total_cur ,
(*mark_debug="true"*)output reg [32-1:0] thr_pos_cur ,
(*mark_debug="true"*)output reg [32-1:0] thr_neg_cur ,
input [16*CH_QTY-1:0] cur_rt_array ,
(*mark_debug="true"*)input [32-1:0] flt_state ,
input [CH_QTY-1:0] flt_ch ,
input [16*CH_QTY-1:0] flt_ch_cur_array ,
(*mark_debug="true"*)input [32-1:0] flt_total_cur ,
(*mark_debug="true"*)input [32-1:0] flt_pos_cur ,
(*mark_debug="true"*)input [32-1:0] flt_neg_cur
);
//*****************************************************************************
// localparam definition
//*****************************************************************************
localparam BRAM_ADDR_TEST_RO = 13'h0000;
localparam BRAM_ADDR_TEST_RW = 13'h0004;
localparam BRAM_ADDR_CUR_EN = 13'h0008;
localparam BRAM_ADDR_CUR_CLEAR_INT = 13'h000C;
localparam BRAM_ADDR_CUR_CFG_REG = 13'h0010;
localparam BRAM_ADDR_CUR_ACQ_PERIOD_US = 13'h0014;
localparam BRAM_ADDR_THR_TOTAL_CUR = 13'h0020;
localparam BRAM_ADDR_THR_POS_CUR = 13'h0024;
localparam BRAM_ADDR_THR_NEG_CUR = 13'h0028;
localparam BRAM_ADDR_FLT_STATE = 13'h0030;
localparam BRAM_ADDR_FLT_CH_L = 13'h0018;
localparam BRAM_ADDR_FLT_CH_H = 13'h001C;
localparam BRAM_ADDR_FLT_TOTAL_CUR = 13'h0034;
localparam BRAM_ADDR_FLT_POS_CUR = 13'h0038;
localparam BRAM_ADDR_FLT_NEG_CUR = 13'h003C;
localparam BRAM_ADDR_CUR_CH_MAP = 13'h0400;
localparam BRAM_ADDR_CUR_THR = 13'h0800;
localparam BRAM_ADDR_CUR_RT = 13'h0C00;
localparam BRAM_ADDR_CUR_FAULT = 13'h1000;
localparam BRAM_ADDR_CUR_MASK = 13'h1C00;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
reg [32-1:0] test_data ;
wire bram_wr_valid ;
wire bram_rd_valid ;
reg [ 8-1:0] ch_map[CH_QTY-1:0] ;
reg [16-1:0] cur_thr[CH_QTY-1:0] ;
wire [16-1:0] cur_rt[CH_QTY-1:0] ;
wire [16-1:0] cur_fault[CH_QTY-1:0] ;
wire [32-1:0] cur_fault_ch[1:0] ;
integer n;
genvar i;
//*****************************************************************************
// Instantiation
//*****************************************************************************
/* vio_cur vio_cur_rt
(
.clk(clk), // input wire clk
.probe_in0(cur_rt[0]), // input wire [63 : 0] probe_in0
.probe_in1(cur_rt[1]), // input wire [63 : 0] probe_in1
.probe_in2(cur_rt[2]), // input wire [63 : 0] probe_in2
.probe_in3(cur_rt[3]), // input wire [63 : 0] probe_in3
.probe_in4(cur_rt[4]), // input wire [63 : 0] probe_in4
.probe_in5(cur_rt[5]), // input wire [63 : 0] probe_in5
.probe_in6(cur_rt[6]), // input wire [63 : 0] probe_in6
.probe_in7(cur_rt[7]), // input wire [63 : 0] probe_in7
.probe_in8(cur_rt[8]), // input wire [63 : 0] probe_in8
.probe_in9(cur_rt[9]), // input wire [63 : 0] probe_in9
.probe_in10(cur_rt[10]), // input wire [63 : 0] probe_in10
.probe_in11(cur_rt[11]), // input wire [63 : 0] probe_in11
.probe_in12(cur_rt[12]), // input wire [63 : 0] probe_in12
.probe_in13(cur_rt[13]), // input wire [63 : 0] probe_in13
.probe_in14(cur_rt[14]), // input wire [63 : 0] probe_in14
.probe_in15(cur_rt[15]) // input wire [63 : 0] probe_in15
// .probe_in16(cur_rt[16]), // input wire [63 : 0] probe_in16
// .probe_in17(cur_rt[17]), // input wire [63 : 0] probe_in17
// .probe_in18(cur_rt[18]), // input wire [63 : 0] probe_in18
// .probe_in19(cur_rt[19]), // input wire [63 : 0] probe_in19
// .probe_in20(cur_rt[20]), // input wire [63 : 0] probe_in20
// .probe_in21(cur_rt[21]), // input wire [63 : 0] probe_in21
// .probe_in22(cur_rt[22]), // input wire [63 : 0] probe_in22
// .probe_in23(cur_rt[23]), // input wire [63 : 0] probe_in23
// .probe_in24(cur_rt[24]), // input wire [63 : 0] probe_in24
// .probe_in25(cur_rt[25]), // input wire [63 : 0] probe_in25
// .probe_in26(cur_rt[26]), // input wire [63 : 0] probe_in26
// .probe_in27(cur_rt[27]), // input wire [63 : 0] probe_in27
// .probe_in28(cur_rt[28]), // input wire [63 : 0] probe_in28
// .probe_in29(cur_rt[29]), // input wire [63 : 0] probe_in29
// .probe_in30(cur_rt[30]), // input wire [63 : 0] probe_in30
// .probe_in31(cur_rt[31]), // input wire [63 : 0] probe_in31
// .probe_in32(cur_rt[32]), // input wire [63 : 0] probe_in32
// .probe_in33(cur_rt[33]), // input wire [63 : 0] probe_in33
// .probe_in34(cur_rt[34]), // input wire [63 : 0] probe_in34
// .probe_in35(cur_rt[35]), // input wire [63 : 0] probe_in35
// .probe_in36(cur_rt[36]), // input wire [63 : 0] probe_in36
// .probe_in37(cur_rt[37]), // input wire [63 : 0] probe_in37
// .probe_in38(cur_rt[38]), // input wire [63 : 0] probe_in38
// .probe_in39(cur_rt[39]), // input wire [63 : 0] probe_in39
// .probe_in40(cur_rt[40]), // input wire [63 : 0] probe_in40
// .probe_in41(cur_rt[41]), // input wire [63 : 0] probe_in41
// .probe_in42(cur_rt[42]), // input wire [63 : 0] probe_in42
// .probe_in43(cur_rt[43]), // input wire [63 : 0] probe_in43
// .probe_in44(cur_rt[44]), // input wire [63 : 0] probe_in44
// .probe_in45(cur_rt[45]), // input wire [63 : 0] probe_in45
// .probe_in46(cur_rt[46]), // input wire [63 : 0] probe_in46
// .probe_in47(cur_rt[47]), // input wire [63 : 0] probe_in47
// .probe_in48(cur_rt[48]), // input wire [63 : 0] probe_in48
// .probe_in49(cur_rt[49]), // input wire [63 : 0] probe_in49
// .probe_in50(cur_rt[50]), // input wire [63 : 0] probe_in50
// .probe_in51(cur_rt[51]), // input wire [63 : 0] probe_in51
// .probe_in52(cur_rt[52]), // input wire [63 : 0] probe_in52
// .probe_in53(cur_rt[53]), // input wire [63 : 0] probe_in53
// .probe_in54(cur_rt[54]), // input wire [63 : 0] probe_in54
// .probe_in55(cur_rt[55]), // input wire [63 : 0] probe_in55
// .probe_in56(cur_rt[56]), // input wire [63 : 0] probe_in56
// .probe_in57(cur_rt[57]), // input wire [63 : 0] probe_in57
// .probe_in58(cur_rt[58]), // input wire [63 : 0] probe_in58
// .probe_in59(cur_rt[59]), // input wire [63 : 0] probe_in59
// .probe_in60(cur_rt[60]), // input wire [63 : 0] probe_in60
// .probe_in61(cur_rt[61]), // input wire [63 : 0] probe_in61
// .probe_in62(cur_rt[62]), // input wire [63 : 0] probe_in62
// .probe_in63(cur_rt[63]) // input wire [63 : 0] probe_in63
);*/
//*****************************************************************************
// Procedural blocks
//*****************************************************************************
//write bram/Set config
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
test_data <= 0;
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_TEST_RW ) )
test_data <= bram_din;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
cnv_en <= 1'b0;
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_CUR_EN ) )
cnv_en <= bram_din[0];
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
clear_int <= 1'b0;
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_CUR_CLEAR_INT ) )
clear_int <= bram_din[0];
else
clear_int <= 1'b0;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
cfg_reg <= {1'b1, 3'b010, 3'b000, 1'b1, 3'b000, 2'b00, 1'b1};
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_CUR_CFG_REG ) )
cfg_reg <= bram_din[13:0];
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
cnv_period_us <= 32'd1000;
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_CUR_ACQ_PERIOD_US ) )
cnv_period_us <= bram_din;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n ) begin
n = 0;
while(n<CH_QTY) begin
ch_map[n] <= 0;
n = n + 1;
end
end else if ( bram_wr_valid && ( (bram_addr & BRAM_ADDR_CUR_MASK) == BRAM_ADDR_CUR_CH_MAP ) )
ch_map[bram_addr[9:2]] <= bram_din[7:0];
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n ) begin
n = 0;
while(n<CH_QTY) begin
cur_thr[n] <= 0;
n = n + 1;
end
end else if ( bram_wr_valid && ( (bram_addr & BRAM_ADDR_CUR_MASK) == BRAM_ADDR_CUR_THR ) )
cur_thr[bram_addr[9:2]] <= bram_din[15:0];
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
thr_total_cur <= 0;
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_THR_TOTAL_CUR ) )
thr_total_cur <= bram_din;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
thr_pos_cur <= 0;
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_THR_POS_CUR ) )
thr_pos_cur <= bram_din;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
thr_neg_cur <= 0;
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_THR_NEG_CUR ) )
thr_neg_cur <= bram_din;
end
//read bram/Get config
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n ) begin
bram_dout <= 0;
end else if ( bram_rd_valid ) begin
if ( bram_addr == BRAM_ADDR_TEST_RO )
bram_dout <= 32'h22222222;
if ( bram_addr == BRAM_ADDR_TEST_RW )
bram_dout <= test_data;
if ( bram_addr == BRAM_ADDR_FLT_STATE )
bram_dout <= flt_state;
if ( bram_addr == BRAM_ADDR_FLT_CH_L )
bram_dout <= {16'b0,flt_ch[15:0]};
// if ( bram_addr == BRAM_ADDR_FLT_CH_H )
// bram_dout <= flt_ch[63:32];
if ( bram_addr == BRAM_ADDR_FLT_TOTAL_CUR )
bram_dout <= flt_total_cur;
if ( bram_addr == BRAM_ADDR_FLT_POS_CUR )
bram_dout <= flt_pos_cur;
if ( bram_addr == BRAM_ADDR_FLT_NEG_CUR )
bram_dout <= flt_neg_cur;
if ( (bram_addr & BRAM_ADDR_CUR_MASK) == BRAM_ADDR_CUR_RT )
bram_dout <= cur_rt[bram_addr[9:2]];
if ( (bram_addr & BRAM_ADDR_CUR_MASK) == BRAM_ADDR_CUR_FAULT )
bram_dout <= cur_fault[bram_addr[9:2]];
end
end
//*****************************************************************************
// Continuous assignments
//*****************************************************************************
assign bram_wr_valid = bram_en && (bram_we == 4'hF);
assign bram_rd_valid = bram_en && (bram_we == 4'h0);
generate
for(i=0;i<CH_QTY;i=i+1) begin : pack
assign ch_map_array[8*i+7 : 8*i] = ch_map[i];
assign thr_ch_cur_array[16*i+15 : 16*i] = cur_thr[i];
end
endgenerate
generate
for(i=0;i<CH_QTY;i=i+1) begin : unpack
assign cur_fault[i] = flt_ch_cur_array[16*i+15 : 16*i];
assign cur_rt[i] = cur_rt_array[16*i+15 : 16*i];
end
endgenerate
endmodule
@@ -0,0 +1,330 @@
`timescale 1 ns / 1 ps
module cur_mon_top#
(
parameter CLK_PERIOD = 10 ,
parameter CHIP_QTY = 2 ,//8
parameter CH_PER_CHIP = 8 ,//8
parameter SPI_QTY = 2 ,//4
parameter SPI_SLAVE_QTY = 2
)
(
input clk ,
input rst_n ,
input [13-1:0] bram_addr ,
input bram_clk ,
input [32-1:0] bram_din ,
output [32-1:0] bram_dout ,
input bram_en ,
input bram_rst ,
input [ 4-1:0] bram_we ,
input [64-1:0] stim_state ,
output interrupt ,
output [CHIP_QTY-1:0] cnv ,
output [ SPI_QTY-1:0] sck ,
output [ SPI_QTY-1:0] mosi ,
input [ SPI_QTY-1:0] miso ,
//--------------------------------------------- AXI
(*mark_debug="true"*)output wire [31:0] axi_i_out ,
(*mark_debug="true"*)output reg axi_i_wr ,
(*mark_debug="true"*)output reg axi_i_tlast ,
output [ 4-1:0] debug_sig
);
//*****************************************************************************
// localparam definition
//*****************************************************************************
localparam CH_QTY = CHIP_QTY*CH_PER_CHIP ;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
wire [ 8*CH_QTY-1:0] ch_map_array ;
wire [14-1:0] cfg_reg ;
wire cnv_en ;
wire [32-1:0] cnv_period_us ;
wire [16*CH_QTY-1:0] thr_ch_cur_array ;
wire [32-1:0] thr_total_cur ;
wire [32-1:0] thr_pos_cur ;
wire [32-1:0] thr_neg_cur ;
wire [16*CH_QTY-1:0] cur_rt_array ;
wire cur_rt_array_update ;
wire [32-1:0] flt_state ;
wire [ CH_QTY-1:0] flt_ch ;
wire [16*CH_QTY-1:0] flt_ch_cur_array ;
wire [32-1:0] flt_total_cur ;
wire [32-1:0] flt_pos_cur ;
wire [32-1:0] flt_neg_cur ;
// wire [ 2-1:0] cnv_start ;
// wire [ 2-1:0] acq_start ;
wire cnv_start ;
wire acq_start ;
wire [24-1:0] axis_acq_tdata[SPI_QTY-1:0] ;
wire axis_acq_tlast[SPI_QTY-1:0] ;
wire axis_acq_tvalid[SPI_QTY-1:0];
wire [24*SPI_QTY-1:0] axis_acq_tdata_array ;
wire [ SPI_QTY-1:0] axis_acq_tlast_array ;
wire [ SPI_QTY-1:0] axis_acq_tvalid_array ;
wire [24-1:0] axis_cur_tdata ;
wire axis_cur_tlast ;
wire axis_cur_tvalid ;
(*mark_debug="true"*)wire fifo_empty ;
(*mark_debug="true"*)wire [31:0] filter_i_fifoout ;
(*mark_debug="true"*)reg filter_i_rd ;
(*mark_debug="true"*)reg [9:0] filter_i_tlast_cnt ;
assign axi_i_out[31:0] = filter_i_fifoout[31:0] ;
always @(posedge clk or negedge rst_n) begin //
if (!rst_n) begin
filter_i_rd <= 'b0;
end else if(filter_i_rd==1'b1)begin
filter_i_rd <= 1'b0;
end else if(fifo_empty==1'b0)begin
filter_i_rd <= 1'b1;
end else begin
filter_i_rd <= 1'b0;
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
filter_i_tlast_cnt[9:0] <= 10'b0;
axi_i_tlast <= 1'b0;
end else if((filter_i_rd==1'b1)&&(filter_i_tlast_cnt[9:0]==10'd999))begin
filter_i_tlast_cnt[9:0] <= 10'b0;
axi_i_tlast <= 1'b1 ;
end else if(filter_i_rd=='b1) begin
filter_i_tlast_cnt[9:0] <= filter_i_tlast_cnt[9:0]+1'b1;
axi_i_tlast <= 1'b0 ;
end else begin
filter_i_tlast_cnt[9:0] <= filter_i_tlast_cnt[9:0];
axi_i_tlast <= 'b0 ;
end
end
always @(posedge clk or negedge rst_n) begin //
if (!rst_n) begin
axi_i_wr <= 'b0;
end else begin
axi_i_wr <= filter_i_rd;
end
end
genvar i;
//*****************************************************************************
// Instantiation
//*****************************************************************************
cur_mon_config#
(
.CH_QTY ( CH_QTY )
)
u_cur_mon_config
(
.clk ( clk ),
.rst_n ( rst_n ),
.bram_addr ( bram_addr ),
.bram_clk ( bram_clk ),
.bram_din ( bram_din ),
.bram_dout ( bram_dout ),
.bram_en ( bram_en ),
.bram_rst ( bram_rst ),
.bram_we ( bram_we ),
.clear_int ( clear_int ),
.ch_map_array ( ch_map_array ),
.cfg_reg ( cfg_reg ),
.cnv_en ( cnv_en ),
.cnv_period_us ( cnv_period_us ),
.thr_ch_cur_array ( thr_ch_cur_array ),
.thr_total_cur ( thr_total_cur ),
.thr_pos_cur ( thr_pos_cur ),
.thr_neg_cur ( thr_neg_cur ),
.cur_rt_array ( cur_rt_array ),
.flt_state ( flt_state ),
.flt_ch ( flt_ch ),
.flt_ch_cur_array ( flt_ch_cur_array ),
.flt_total_cur ( flt_total_cur ),
.flt_pos_cur ( flt_pos_cur ),
.flt_neg_cur ( flt_neg_cur )
);
ad7689_dual_ctrl#
(
.CLK_PERIOD ( CLK_PERIOD )//10
)
u_ad7689_dual_ctrl
(
.clk ( clk ),
.rst_n ( rst_n ),
.enable ( cnv_en ),
.cnv_start ( cnv_start ),
.acq_start ( acq_start )
);
generate
for(i=0;i<SPI_QTY;i=i+1) begin : acquisition
ad7689_dual_if#
(
.CLK_PERIOD ( CLK_PERIOD )//10
)
u_ad7689_dual_if
(
.clk ( clk ),
.rst_n ( rst_n ),
.enable ( cnv_en ),
.cnv_start ( cnv_start ),
.acq_start ( acq_start ),
.m_axis_acq_tdata ( axis_acq_tdata[i] ),
.m_axis_acq_tlast ( axis_acq_tlast[i] ),
.m_axis_acq_tvalid ( axis_acq_tvalid[i] ),
.cnv ( cnv[i] ),
.sck ( sck[i] ),
.mosi ( mosi[i] ),
.miso ( miso[i] )
);
end
endgenerate
acq_collect#
(
.CLK_PERIOD ( CLK_PERIOD ),
.SPI_QTY ( SPI_QTY ),
.CH_OF_SPI ( 8 ) //16
)
u_acq_collect
(
.clk ( clk ),
.rst_n ( rst_n ),
.s_axis_tdata_array ( axis_acq_tdata_array ),
.s_axis_tlast_array ( axis_acq_tlast_array ),
.s_axis_tvalid_array ( axis_acq_tvalid_array ),
.m_axis_tdata ( axis_cur_tdata ),
.m_axis_tlast ( axis_cur_tlast ),
.m_axis_tvalid ( axis_cur_tvalid )
);
cur_ch_map#
(
.CLK_PERIOD ( CLK_PERIOD ),
.CH_QTY ( CH_QTY )
)
u_cur_ch_map
(
.clk ( clk ),
.rst_n ( rst_n ),
.ch_map_array ( ch_map_array ),
.s_axis_tdata ( axis_cur_tdata ),
.s_axis_tlast ( axis_cur_tlast ),
.s_axis_tvalid ( axis_cur_tvalid ),
.cur_array_update ( cur_rt_array_update ),
.cur_array ( cur_rt_array )
);
cur_monitor#
(
.CLK_PERIOD ( CLK_PERIOD ),
.CH_QTY ( CH_QTY )
)
u_cur_monitor
(
.clk ( clk ),
.rst_n ( rst_n ),
.thr_ch_cur_array ( thr_ch_cur_array ),
.thr_total_cur ( thr_total_cur ),
.thr_pos_cur ( thr_pos_cur ),
.thr_neg_cur ( thr_neg_cur ),
.clear_int ( clear_int ),
.stim_state ( stim_state ),
.cur_rt_update ( cur_rt_array_update ),
.cur_rt_array ( cur_rt_array ),
.interrupt ( interrupt ),
.flt_state ( flt_state ),
.flt_ch ( flt_ch ),
.flt_ch_cur_array ( flt_ch_cur_array ),
.flt_total_cur ( flt_total_cur ),
.flt_pos_cur ( flt_pos_cur ),
.flt_neg_cur ( flt_neg_cur )
);
vio_cur_flt_state u_vio_cur_flt_state
(
.clk ( clk ), // input wire clk
.probe_in0 ( interrupt ), // input wire [0 : 0] probe_in0
.probe_in1 ( flt_state ), // input wire [31 : 0] probe_in1
.probe_in2 ( flt_ch ) // input wire [63 : 0] probe_in2
);
fifo_generator_1 u0_fifo_generator_1(
.full( ),
.din({8'b0,axis_cur_tdata[23:0]}),
.wr_en(axis_cur_tvalid),
.empty(fifo_empty ),
.dout(filter_i_fifoout[31:0]),
.rd_en(filter_i_rd),//
.rst(~rst_n),
.wr_clk(clk),
.rd_clk(clk) //clk_100m
);
//*****************************************************************************
// Procedural blocks
//*****************************************************************************
//*****************************************************************************
// Wire assignment
//*****************************************************************************
generate
for(i=0;i<SPI_QTY;i=i+1) begin : pack
assign axis_acq_tdata_array[24*i+23 : 24*i] = axis_acq_tdata[i];
assign axis_acq_tlast_array[i] = axis_acq_tlast[i];
assign axis_acq_tvalid_array[i] = axis_acq_tvalid[i];
end
endgenerate
assign debug_sig[0] = 1'b0;//cnv[0];
assign debug_sig[1] = 1'b0;//sck[0];
assign debug_sig[2] = 1'b0;//mosi[0];
assign debug_sig[3] = 1'b0;//miso[0];
endmodule
@@ -0,0 +1,259 @@
`timescale 1ns/1ps
module cur_mon_top_tb();
//*****************************************************************************
// Parameter definition
//*****************************************************************************
localparam T_CLK = 10 ; //ns
localparam CH_QTY = 16 ;//64
localparam BRAM_ADDR_TEST_RO = 13'h0000;
localparam BRAM_ADDR_TEST_RW = 13'h0004;
localparam BRAM_ADDR_CUR_EN = 13'h0008;
localparam BRAM_ADDR_CUR_CLEAR_INT = 13'h000C;
localparam BRAM_ADDR_CUR_CFG_REG = 13'h0010;
localparam BRAM_ADDR_CUR_ACQ_PERIOD_US = 13'h0014;
localparam BRAM_ADDR_CUR_FAULT_CH_L = 13'h0018;
localparam BRAM_ADDR_CUR_FAULT_CH_H = 13'h001C;
localparam BRAM_ADDR_THR_TOTAL_CUR = 13'h0020;
localparam BRAM_ADDR_THR_POS_CUR = 13'h0024;
localparam BRAM_ADDR_THR_NEG_CUR = 13'h0028;
localparam BRAM_ADDR_CUR_CH_MAP = 13'h0400;
localparam BRAM_ADDR_CUR_THR = 13'h0800;
localparam BRAM_ADDR_CUR_RT = 13'h0C00;
localparam BRAM_ADDR_CUR_FAULT = 13'h1000;
localparam BRAM_ADDR_CUR_MASK = 13'h1C00;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
reg clk ;
reg rst_n ;
reg [13-1:0] bram_addr ;
// reg bram_clk ;
reg [32-1:0] bram_din ;
wire [32-1:0] bram_dout ;
reg bram_en ;
reg bram_rst ;
reg [ 4-1:0] bram_we ;
reg [64-1:0] stim_en ;
wire [ 1:0] cnv ;
wire [ 1:0] sck ;
wire [ 1:0] mosi ;
wire [ 1:0] miso ;
genvar i;
integer n;
//*****************************************************************************
// Wire assignment
//*****************************************************************************
always #( T_CLK/2.0 ) clk = !clk;
initial begin
Initial();
#100 rst_n = 0;
#100 rst_n = 1;
//Config DDS
write_bram(BRAM_ADDR_CUR_CFG_REG, {1'b1, 3'b010, 3'b000, 1'b1, 3'b000, 2'b00, 1'b1});
write_bram(BRAM_ADDR_CUR_ACQ_PERIOD_US, 32'd1000);
// for(n=0;n<CH_QTY;n=n+1) begin
// write_bram(BRAM_ADDR_CUR_CH_MAP + 4*n, (63-n));
// end
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h00, 13);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h04, 9);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h08, 10);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h0C, 15);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h10, 14);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h14, 6);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h18, 4);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h1C, 5);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h20, 8);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h24, 7);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h28, 2);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h2C, 0);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h30, 1);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h34, 3);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h38, 11);
write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h3C, 12);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h00, 58);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h04, 59);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h08, 52);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h0C, 49);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h10, 50);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h14, 63);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h18, 48);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h1C, 62);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h20, 23);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h24, 13);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h28, 9);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h2C, 10);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h30, 56);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h34, 15);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h38, 54);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h3C, 14);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h40, 39);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h44, 36);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h48, 33);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h4C, 17);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h50, 46);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h54, 47);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h58, 42);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h5C, 45);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h60, 40);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h64, 41);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h68, 38);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h6C, 35);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h70, 32);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h74, 34);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h78, 16);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h7C, 37);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h80, 6);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h84, 26);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h88, 4);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h8C, 5);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h90, 24);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h94, 21);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h98, 8);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'h9C, 30);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hA0, 55);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hA4, 57);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hA8, 53);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hAC, 51);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hB0, 44);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hB4, 61);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hB8, 43);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hBC, 60);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hC0, 18);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hC4, 20);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hC8, 31);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hCC, 28);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hD0, 7);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hD4, 25);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hD8, 2);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hDC, 0);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hE0, 1);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hE4, 3);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hE8, 11);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hEC, 12);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hF0, 22);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hF4, 19);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hF8, 29);
// write_bram(BRAM_ADDR_CUR_CH_MAP + 8'hFC, 27);
for(n=0;n<CH_QTY;n=n+1) begin
write_bram(BRAM_ADDR_CUR_THR + 4*n, 32'd33);
end
////
write_bram(BRAM_ADDR_THR_TOTAL_CUR, 32'd58000);
write_bram(BRAM_ADDR_THR_POS_CUR, 32'd58500);
write_bram(BRAM_ADDR_THR_NEG_CUR, 32'd50000);
write_bram(BRAM_ADDR_CUR_CLEAR_INT, 32'd1);
write_bram(BRAM_ADDR_CUR_EN, 32'd1);
#6000000;
// write_bram(BRAM_ADDR_CUR_CLEAR_INT, 32'd1);
end
//*****************************************************************************
// Task
//*****************************************************************************
task Initial;
begin
clk <= 1'b0 ;
rst_n <= 1'b0 ;
stim_en <= 64'hFFFF0000FFFF0000;
end
endtask
task write_bram;
input [12:0] addr;
input [31:0] data;
begin
@ ( posedge clk );
bram_addr <= addr;
bram_din <= data;
bram_en <= 1;
bram_we <= 4'hF ;
@ ( posedge clk );
bram_en <= 0;
bram_we <= 4'h0;
end
endtask
task read_bram;
input [12:0] addr;
output [31:0] data;
begin
@ ( posedge clk );
bram_addr <= addr;
bram_en <= 1;
bram_we <= 4'h0 ;
@ ( posedge clk );
bram_en <= 0;
@ ( posedge clk );
data <= bram_dout;
end
endtask
//*****************************************************************************
// Instantiation
//*****************************************************************************
cur_mon_top#
(
.CLK_PERIOD ( 10 )//10 500 500
)
DUT
(
.clk ( clk ),
.rst_n ( rst_n ),
.bram_addr ( bram_addr ),
.bram_clk ( 1'b0 ),
.bram_din ( bram_din ),
.bram_dout ( bram_dout ),
.bram_en ( bram_en ),
.bram_rst ( bram_rst ),
.bram_we ( bram_we ),
.stim_state ( stim_en ),
.interrupt ( interrupt ),
.cnv ( cnv ),
.sck ( sck ),
.mosi ( mosi ),
.miso ( miso )
);
generate
for(i=0;i<2;i=i+1) begin : ad7689
ad7689_mod u_ad7689_mod
(
.init_data ( i*-256 ),
.cnv ( cnv[i] ),
.sck ( sck[i] ),
.mosi ( mosi[i] ),
.miso ( miso[i] )
);
end
endgenerate
endmodule
@@ -0,0 +1,254 @@
`timescale 1 ns / 1 ps
module cur_monitor#
(
parameter CLK_PERIOD = 10 ,
parameter CH_QTY = 64
)
(
input clk ,
input rst_n ,
input [16*CH_QTY-1:0] thr_ch_cur_array ,
input [32-1:0] thr_total_cur ,
input [32-1:0] thr_pos_cur ,
input [32-1:0] thr_neg_cur ,
input clear_int ,
input [64-1:0] stim_state ,
input cur_rt_update ,
input [16*CH_QTY-1:0] cur_rt_array ,
output reg interrupt ,
output reg [32-1:0] flt_state ,
output reg [CH_QTY-1:0] flt_ch ,
output [16*CH_QTY-1:0] flt_ch_cur_array ,
output reg [32-1:0] flt_total_cur ,
output reg [32-1:0] flt_pos_cur ,
output reg [32-1:0] flt_neg_cur
);
//*****************************************************************************
// localparam definition
//*****************************************************************************
localparam IDLE = 4'd0;
localparam SCAN_ST = 4'd1;
localparam END_ST = 4'd2;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
(*mark_debug="true"*)reg [ 4-1:0] cstate ;
(*mark_debug="true"*)reg [ 4-1:0] nstate ;
(*mark_debug="true"*)reg [ 8-1:0] scan_cnt ;
(*mark_debug="true"*)wire [16-1:0] current ;
wire [16-1:0] thr_ch_cur[0:CH_QTY-1] ;
wire [16-1:0] cur_rt[0:CH_QTY-1] ;
wire [16-1:0] cur_rt_u[0:CH_QTY-1] ;
reg [16-1:0] flt_ch_cur[0:CH_QTY-1] ;
(*mark_debug="true"*)reg sclr ;
(*mark_debug="true"*)wire [16-1:0] cur_total ;
(*mark_debug="true"*)wire [16-1:0] cur_pos ;
wire [16-1:0] cur_neg ;
wire [32-1:0] sum_total ;
wire [32-1:0] sum_pos ;
wire [32-1:0] sum_neg ;
wire [32-1:0] u_sum_total ;
wire [32-1:0] u_sum_pos ;
wire [32-1:0] u_sum_neg ;
(*mark_debug="true"*)wire cur_flt_ch ;
(*mark_debug="true"*)reg cur_flt_total ;
(*mark_debug="true"*)reg cur_flt_pos ;
(*mark_debug="true"*)reg cur_flt_neg ;
(*mark_debug="true"*)wire [ 4-1:0] flt_bits ;
integer i;
genvar j;
//*****************************************************************************
// Instantiation
//*****************************************************************************
c_add_s16_s32 u_add_total
(
.A ( cur_total ), // input wire [15 : 0] A
.B ( sum_total ), // input wire [31 : 0] B
.CLK ( clk ), // input wire CLK
.CE ( 1'b1 ), // input wire CE
.SCLR ( sclr ), // input wire SCLR
.S ( sum_total ) // output wire [31 : 0] S
);
c_add_s16_s32 u_add_positive
(
.A ( cur_pos ), // input wire [15 : 0] A
.B ( sum_pos ), // input wire [31 : 0] B
.CLK ( clk ), // input wire CLK
.CE ( 1'b1 ), // input wire CE
.SCLR ( sclr ), // input wire SCLR
.S ( sum_pos ) // output wire [31 : 0] S
);
c_add_s16_s32 u_add_negative
(
.A ( cur_neg ), // input wire [15 : 0] A
.B ( sum_neg ), // input wire [31 : 0] B
.CLK ( clk ), // input wire CLK
.CE ( 1'b1 ), // input wire CE
.SCLR ( sclr ), // input wire SCLR
.S ( sum_neg ) // output wire [31 : 0] S
);
//*****************************************************************************
// Procedural blocks
//*****************************************************************************
always@( posedge clk or negedge rst_n ) begin
if( !rst_n ) cstate <= IDLE;
else cstate <= nstate;
end
always@( * ) begin
case ( cstate )
IDLE:
if ( cur_rt_update )
nstate <= SCAN_ST;
else
nstate <= IDLE;
SCAN_ST:
if( scan_cnt == CH_QTY - 1 )
nstate <= END_ST;
else
nstate <= SCAN_ST;
END_ST:
nstate <= IDLE;
default:
nstate <= IDLE;
endcase
end
always @ ( posedge clk ) begin
if ( cstate == SCAN_ST && nstate == SCAN_ST )
scan_cnt <= scan_cnt + 1'b1;
else
scan_cnt <= 0;
end
// single channel
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
flt_ch <= 0;
for (i=0; i<CH_QTY; i=i+1) begin
flt_ch_cur[i] <= 0;
end
end else if ( clear_int ) begin
flt_ch <= 0;
for (i=0; i<CH_QTY; i=i+1) begin
flt_ch_cur[i] <= 0;
end
end else if ( cstate == SCAN_ST && cur_rt_u[scan_cnt] > thr_ch_cur[scan_cnt] ) begin
flt_ch[scan_cnt] <= 1'b1;
flt_ch_cur[scan_cnt] <= cur_rt[scan_cnt];
end
end
// summation
always @ ( posedge clk ) begin
if ( cstate == SCAN_ST || nstate == SCAN_ST )
sclr <= 1'b0;
else
sclr <= 1'b1;
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
cur_flt_total <= 1'b0;
flt_total_cur <= 0;
end else if ( clear_int ) begin
cur_flt_total <= 1'b0;
flt_total_cur <= 0;
end else if ( cstate == END_ST && (u_sum_total > thr_total_cur) ) begin
cur_flt_total <= 1'b1;
flt_total_cur <= sum_total;
end
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
cur_flt_pos <= 1'b0;
flt_pos_cur <= 0;
end else if ( clear_int ) begin
cur_flt_pos <= 1'b0;
flt_pos_cur <= 0;
end else if ( cstate == END_ST && (u_sum_pos > thr_pos_cur) ) begin
cur_flt_pos <= 1'b1;
flt_pos_cur <= sum_pos;
end
end
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
cur_flt_neg <= 1'b0;
flt_neg_cur <= 0;
end else if ( clear_int ) begin
cur_flt_neg <= 1'b0;
flt_neg_cur <= 0;
end else if ( cstate == END_ST && (u_sum_neg > thr_neg_cur) ) begin
cur_flt_neg <= 1'b1;
flt_neg_cur <= sum_neg;
end
end
// interrupt
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
interrupt <= 1'b0;
flt_state <= 0;
end else if ( clear_int ) begin
interrupt <= 1'b0;
flt_state <= 0;
end else if ( flt_bits ) begin
interrupt <= 1'b1;
flt_state <= {28'd0, flt_bits};
end
end
//*****************************************************************************
// Wire assignment
//*****************************************************************************
generate
for(j=0;j<CH_QTY;j=j+1) begin : unpack
assign thr_ch_cur[j] = thr_ch_cur_array[16*j+15 : 16*j];
assign cur_rt[j] = cur_rt_array[16*j+15 : 16*j];
assign cur_rt_u[j] = (cur_rt[j][15])? ~(cur_rt[j]-1'b1) : cur_rt[j];
end
endgenerate
generate
for(j=0;j<CH_QTY;j=j+1) begin : pack
assign flt_ch_cur_array[16*j+15 : 16*j] = flt_ch_cur[j];
end
endgenerate
assign cur_flt_ch = flt_ch? 1'b1:1'b0;
assign current = cur_rt[scan_cnt];
assign cur_total = current;
assign cur_pos = current[15]? 0:current;
assign cur_neg = current[15]? current:0;
assign u_sum_total = (sum_total[31])? ~(sum_total-1'b1) : sum_total;
assign u_sum_pos = (sum_pos[31])? ~(sum_pos-1'b1) : sum_pos;
assign u_sum_neg = (sum_neg[31])? ~(sum_neg-1'b1) : sum_neg;
assign flt_bits = {cur_flt_neg, cur_flt_pos, cur_flt_total, cur_flt_ch};
endmodule