Files
2024-10-28 13:14:49 +08:00

364 lines
11 KiB
Verilog

`timescale 1 ns / 1 ps
module transmit_config#
(
parameter CHIPSET_QTY = 4
)
(
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 [CHIPSET_QTY-1:0] stim_en ,
output reg [32-1:0] update_period ,
output reg enable_timer ,
output reg dds_by_ps ,
output reg dds_aclken ,
output dds_aresetn ,
output reg sw_enable ,
output reg sw_data_sel ,
output reg [64-1:0] sw_data_0 ,
input [64-1:0] sw_state ,
output [ 8*16*CHIPSET_QTY-1:0] stim_trim_p_array_array ,
output [ 8*16*CHIPSET_QTY-1:0] stim_trim_n_array_array ,
output reg phase_enable ,
output [32*16-1:0] phase_inc_array ,
output [32*16-1:0] phase_off_array ,
input [64-1:0] stim_monitor_rt ,
input [64-1:0] stim_monitor_latch ,
output [ 1*CHIPSET_QTY-1:0] spi_cmd_valid_array ,
output [32*CHIPSET_QTY-1:0] spi_cmd_data_array ,
input [ 1*CHIPSET_QTY-1:0] spi_cmd_ready_array ,
input [ 1*CHIPSET_QTY-1:0] spi_res_en_array ,
input [32*CHIPSET_QTY-1:0] spi_res_array
);
//*****************************************************************************
// localparam definition
//*****************************************************************************
localparam BRAM_ADDR_TEST_RW = 13'h0000;
localparam BRAM_ADDR_TEST_RO_DATA = 13'h0004;
localparam BRAM_ADDR_STIM_ENABLE = 13'h0010;
localparam BRAM_ADDR_UPDATE_PERIOD = 13'h0020;
localparam BRAM_ADDR_UPLOAD_ROUND_NUM = 13'h0024; //Unused
localparam BRAM_ADDR_ENABLE = 13'h0028;
localparam BRAM_ADDR_DDS_CTRL = 13'h002C;
localparam BRAM_ADDR_DDS_PHASE_TRIG = 13'h0030; //Unused
localparam BRAM_ADDR_SWITCH_CTRL = 13'h0034;
localparam BRAM_ADDR_SWITCH_DATA0 = 13'h0040;
localparam BRAM_ADDR_SWITCH_DATA1 = 13'h0044;
localparam BRAM_ADDR_CUR_MON_RESET = 13'h0048; //Unused
localparam BRAM_ADDR_CUR_MON_STATE0 = 13'h0050;
localparam BRAM_ADDR_CUR_MON_STATE1 = 13'h0054;
localparam BRAM_ADDR_CUR_MON_LATCH0 = 13'h0060;
localparam BRAM_ADDR_CUR_MON_LATCH1 = 13'h0064;
localparam BRAM_ADDR_SPI_STATE_MASK = 13'h1F80;
localparam BRAM_ADDR_SPI_STATE_START = 13'h0100;
localparam BRAM_ADDR_SPI_TX_MASK = 13'h1F80;
localparam BRAM_ADDR_SPI_TX_START = 13'h0180;
localparam BRAM_ADDR_SPI_RX_MASK = 13'h1F80;
localparam BRAM_ADDR_SPI_RX_START = 13'h0200;
localparam BRAM_ADDR_SPI_ERR_MASK = 13'h1F80;
localparam BRAM_ADDR_SPI_ERR_START = 13'h0280;
localparam BRAM_ADDR_DDS_PHASE_INC_MASK = 13'h1F80;
localparam BRAM_ADDR_DDS_PHASE_INC_START = 13'h0400;
localparam BRAM_ADDR_DDS_PHASE_OFF_MASK = 13'h1F80;
localparam BRAM_ADDR_DDS_PHASE_OFF_START = 13'h0480;
localparam BRAM_ADDR_STIM_TRIM_P_MASK = 13'h1F00;
localparam BRAM_ADDR_STIM_TRIM_P_START = 13'h0600;
localparam BRAM_ADDR_STIM_TRIM_N_MASK = 13'h1F00;
localparam BRAM_ADDR_STIM_TRIM_N_START = 13'h0700;
//*****************************************************************************
// Internal register and wire declarations
//*****************************************************************************
reg [32-1:0] test_data ;
wire bram_wr_valid ;
wire bram_rd_valid ;
reg [32-1:0] spi_state_r[0:CHIPSET_QTY-1] ;
reg dds_areset ;
reg [32-1:0] spi_cmd_data[0:CHIPSET_QTY-1] ;
reg spi_cmd_valid[0:CHIPSET_QTY-1] ;
wire spi_cmd_ready[0:CHIPSET_QTY-1] ;
wire spi_res_en[0:CHIPSET_QTY-1] ;
wire [32-1:0] spi_res[0:CHIPSET_QTY-1] ;
reg [32-1:0] spi_res_r[0:CHIPSET_QTY-1] ;
reg [ 8-1:0] stim_trim_p[0:16*CHIPSET_QTY-1] ;
reg [ 8-1:0] stim_trim_n[0:16*CHIPSET_QTY-1] ;
reg [32-1:0] dds_phase_inc[0:16-1] ;
reg [32-1:0] dds_phase_off[0:16-1] ;
reg [32-1:0] unknow_data ;
reg [ 5-1:0] spi_cmd_chip ;
integer n;
genvar i;
genvar j;
//*****************************************************************************
// Procedural blocks
//*****************************************************************************
generate
for(i=0;i<CHIPSET_QTY;i=i+1) begin : spi_state
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n ) begin
spi_state_r[i] <= 0;
end else if ( spi_res_en[i] ) begin
spi_state_r[i][0] <= spi_state_r[i][0] | spi_res_en[i];
end else if ( (bram_addr & BRAM_ADDR_SPI_STATE_MASK) == BRAM_ADDR_SPI_STATE_START ) begin
if (bram_addr[6:2]==i)
spi_state_r[i] <= 0;
end
end
end
endgenerate
generate
for(i=0;i<CHIPSET_QTY;i=i+1) begin : spi_rx
always @ ( posedge clk or negedge rst_n ) begin
if ( !rst_n )
spi_res_r[i] <= 0;
else if ( spi_res_en[i] )
spi_res_r[i] <= spi_res[i];
end
end
endgenerate
//write bram/Set config
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
stim_en <= 1'b0;
else if ( bram_wr_valid && ( bram_addr == BRAM_ADDR_STIM_ENABLE ) )
stim_en <= bram_din[CHIPSET_QTY-1:0];
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n ) begin
n = 0;
while(n<16) begin
dds_phase_inc[n] <= 32'h0015493D;//3kHz: 32'h003EEA21, 10kHz: 32'h00D1B717
n = n + 1;
end
end else if ( bram_wr_valid && ( (bram_addr & BRAM_ADDR_DDS_PHASE_INC_MASK) == BRAM_ADDR_DDS_PHASE_INC_START ) )
dds_phase_inc[bram_addr[6:2]] <= bram_din;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n ) begin
n = 0;
while(n<16) begin
dds_phase_off[n] <= 0;
n = n + 1;
end
end else if ( bram_wr_valid && ( (bram_addr & BRAM_ADDR_DDS_PHASE_OFF_MASK) == BRAM_ADDR_DDS_PHASE_OFF_START ) )
dds_phase_off[bram_addr[6:2]] <= bram_din;
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n ) begin
n = 0;
while(n<16*CHIPSET_QTY) begin
stim_trim_p[n] <= 8'h80;
n = n + 1;
end
end else if ( bram_wr_valid && ( (bram_addr & BRAM_ADDR_STIM_TRIM_P_MASK) == BRAM_ADDR_STIM_TRIM_P_START ) ) begin
stim_trim_p[(bram_addr[7:2]<<2)+0] <= bram_din[ 7: 0];
stim_trim_p[(bram_addr[7:2]<<2)+1] <= bram_din[15: 8];
stim_trim_p[(bram_addr[7:2]<<2)+2] <= bram_din[23:16];
stim_trim_p[(bram_addr[7:2]<<2)+3] <= bram_din[31:24];
end
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n ) begin
n = 0;
while(n<16*CHIPSET_QTY) begin
stim_trim_n[n] <= 8'h80;
n = n + 1;
end
end else if ( bram_wr_valid && ( (bram_addr & BRAM_ADDR_STIM_TRIM_N_MASK) == BRAM_ADDR_STIM_TRIM_N_START ) )begin
stim_trim_n[(bram_addr[7:2]<<2)+0] <= bram_din[ 7: 0];
stim_trim_n[(bram_addr[7:2]<<2)+1] <= bram_din[15: 8];
stim_trim_n[(bram_addr[7:2]<<2)+2] <= bram_din[23:16];
stim_trim_n[(bram_addr[7:2]<<2)+3] <= bram_din[31:24];
end
end
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n ) begin
spi_cmd_chip <= 0;
n = 0;
while(n<CHIPSET_QTY) begin
spi_cmd_data[n] <= 0;
spi_cmd_valid[n] <= 1'b0;
n = n + 1;
end
end else if ( bram_wr_valid && ( (bram_addr & BRAM_ADDR_SPI_TX_MASK) == BRAM_ADDR_SPI_TX_START ) ) begin
spi_cmd_data[bram_addr[6:2]] <= bram_din;
spi_cmd_valid[bram_addr[6:2]] <= 1'b1;
spi_cmd_chip <= bram_addr[6:2];
end else if ( spi_cmd_valid[spi_cmd_chip] && spi_cmd_ready[spi_cmd_chip] ) begin
spi_cmd_valid[spi_cmd_chip] <= 1'b0;
end
end
//write bram/Set config
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n ) begin
test_data <= 0;
update_period <= 0;
enable_timer <= 1'b0;
dds_by_ps <= 1'b1;
dds_aclken <= 1'b0;
dds_areset <= 1'b0;
phase_enable <= 1'b0;
sw_enable <= 1'b0;
sw_data_sel <= 1'b0;
sw_data_0 <= 0;
end else if ( bram_en && (bram_we == 4'hF) ) begin
case ( bram_addr[12:0] )
BRAM_ADDR_TEST_RW : test_data <= bram_din;
BRAM_ADDR_UPDATE_PERIOD : update_period <= bram_din;
BRAM_ADDR_ENABLE : enable_timer <= bram_din[0];
BRAM_ADDR_DDS_CTRL : begin
phase_enable <= bram_din[3];
dds_areset <= bram_din[2];
dds_aclken <= bram_din[1];
dds_by_ps <= bram_din[0];
end
BRAM_ADDR_SWITCH_CTRL : begin
sw_enable <= bram_din[0];
sw_data_sel <= bram_din[1];
end
BRAM_ADDR_SWITCH_DATA0 : sw_data_0[31: 0]<= bram_din;
BRAM_ADDR_SWITCH_DATA1 : sw_data_0[63:32]<= bram_din;
default:
unknow_data <= bram_din;
endcase
end else begin
phase_enable <= 1'b0;
dds_areset <= 1'b0;
end
end
//read bram/Get config
always @ ( posedge clk or negedge rst_n ) begin
if( !rst_n )
bram_dout <= 0;
else if ( bram_en && (bram_we == 4'h0) ) begin
case ( bram_addr[12:0] )
BRAM_ADDR_TEST_RW : bram_dout <= test_data;
BRAM_ADDR_TEST_RO_DATA : bram_dout <= 32'h12345678;
BRAM_ADDR_UPDATE_PERIOD : bram_dout <= update_period;
BRAM_ADDR_ENABLE : bram_dout <= {{31{1'b0}}, enable_timer};
BRAM_ADDR_DDS_CTRL : bram_dout <= {{29{1'b0}}, dds_areset, dds_aclken, dds_by_ps};
BRAM_ADDR_SWITCH_CTRL : bram_dout <= {{30{1'b0}}, sw_data_sel, sw_enable};
BRAM_ADDR_SWITCH_DATA0 : bram_dout <= sw_state[31: 0];
BRAM_ADDR_SWITCH_DATA1 : bram_dout <= sw_state[63:32];
BRAM_ADDR_CUR_MON_STATE0 : bram_dout <= stim_monitor_rt[31: 0];
BRAM_ADDR_CUR_MON_STATE1 : bram_dout <= stim_monitor_rt[63:32];
BRAM_ADDR_CUR_MON_LATCH0 : bram_dout <= stim_monitor_latch[31: 0];
BRAM_ADDR_CUR_MON_LATCH1 : bram_dout <= stim_monitor_latch[63:32];
default: bram_dout <= 0;
endcase
if ( (bram_addr & BRAM_ADDR_SPI_STATE_MASK) == BRAM_ADDR_SPI_STATE_START )
bram_dout <= spi_state_r[bram_addr[6:2]];
if ( (bram_addr & BRAM_ADDR_SPI_RX_MASK) == BRAM_ADDR_SPI_RX_START )
bram_dout <= spi_res_r[bram_addr[6: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);
assign dds_aresetn = ~dds_areset;
generate
for(i=0;i<CHIPSET_QTY;i=i+1) begin : pack
assign spi_cmd_valid_array[i] = spi_cmd_valid[i];
assign spi_cmd_data_array[32*i+31 : 32*i] = spi_cmd_data[i];
end
endgenerate
generate
for(i=0;i<CHIPSET_QTY;i=i+1) begin : unpack
assign spi_cmd_ready[i] = spi_cmd_ready_array[i];
end
endgenerate
generate
for(i=0;i<CHIPSET_QTY;i=i+1) begin : pack_trim_p
for(j=0;j<16;j=j+1) begin : pack
assign stim_trim_p_array_array[8*(16*i+j)+7 : 8*(16*i+j)] = stim_trim_p[16*i+j];
end
end
endgenerate
generate
for(i=0;i<CHIPSET_QTY;i=i+1) begin : pack_trim_n
for(j=0;j<16;j=j+1) begin : pack
assign stim_trim_n_array_array[8*(16*i+j)+7 : 8*(16*i+j)] = stim_trim_n[16*i+j];
end
end
endgenerate
generate
for(i=0;i<16;i=i+1) begin : pack_dds
assign phase_inc_array[32*i+31 : 32*i] = dds_phase_inc[i];
assign phase_off_array[32*i+31 : 32*i] = dds_phase_off[i];
end
endgenerate
generate
for(i=0;i<CHIPSET_QTY;i=i+1) begin : unpack_res
assign spi_res_en[i] = spi_res_en_array[i];
assign spi_res[i] = spi_res_array[32*i+31 : 32*i];
end
endgenerate
endmodule