339 lines
9.4 KiB
Verilog
339 lines
9.4 KiB
Verilog
`timescale 1 ns / 1 ps
|
|
|
|
module transmit_if#
|
|
(
|
|
parameter SPI_CLK_DIV = 2 ,
|
|
parameter SPI_DATA_WIDTH = 32 ,
|
|
parameter CH_OF_CHIPSET = 16 ,
|
|
|
|
parameter CMD_CONVERT = 2'b00 ,
|
|
parameter CMD_EXTEND = 2'b01 ,
|
|
parameter CMD_WRITE = 2'b10 ,
|
|
parameter CMD_READ = 2'b11 ,
|
|
|
|
parameter REG_ADDR_MONITOR = 8'd40 ,//Read Only
|
|
parameter REG_ADDR_POS_CUR = 8'd64 ,
|
|
parameter REG_ADDR_NEG_CUR = 8'd96
|
|
)
|
|
(
|
|
input clk ,
|
|
input rst_n ,
|
|
|
|
input trans_round ,
|
|
input trans_pulse ,
|
|
|
|
//------------------------------------------ spi direct communication
|
|
input spi_cmd_valid ,
|
|
input [32-1:0] spi_cmd_data ,
|
|
output reg spi_cmd_ready ,
|
|
|
|
output reg spi_res_en ,
|
|
output reg [32-1:0] spi_res ,
|
|
|
|
//------------------------------------------ conver/stim stream tx
|
|
input s_axis_trans_tlast ,
|
|
input [32-1:0] s_axis_trans_tdata ,
|
|
output reg s_axis_trans_tready ,
|
|
input s_axis_trans_tvalid ,
|
|
|
|
//------------------------------------------ record stream rx
|
|
output reg [32-1:0] cnv_res_tdata ,
|
|
output cnv_res_tlast ,
|
|
input cnv_res_tready ,
|
|
output reg cnv_res_tvalid ,
|
|
|
|
//------------------------------------------ monitor
|
|
output reg monitor_data_en ,
|
|
output reg [16-1:0] monitor_data ,
|
|
|
|
output reg [16-1:0] stim_state ,
|
|
output reg [32-1:0] stim_stage_code ,
|
|
|
|
//------------------------------------------ device spi
|
|
output cs ,
|
|
output sclk ,
|
|
output mosi ,
|
|
input miso
|
|
);
|
|
|
|
//*****************************************************************************
|
|
// localparam definition
|
|
//*****************************************************************************
|
|
localparam SYNC_ST = 4'h0 ;
|
|
localparam TRANS_ST = 4'h1 ;
|
|
|
|
//*****************************************************************************
|
|
// Internal register and wire declarations
|
|
//*****************************************************************************
|
|
reg [32-1:0] spi_data ;
|
|
reg spi_data_en ;
|
|
reg spi_flag ;
|
|
|
|
wire is_empty_cmd ;
|
|
wire is_stim_cmd ;
|
|
wire is_cover_cmd ;
|
|
wire is_cnv_cmd ;
|
|
wire is_mon_cmd ;
|
|
|
|
wire stim_pol ;
|
|
wire [ 4-1:0] stim_ch ;
|
|
wire [ 8-1:0] stim_reg_addr ;
|
|
wire [32-1:0] stim_cmd ;
|
|
|
|
reg [32-1:0] trans_data ;
|
|
reg trans_data_en ;
|
|
|
|
reg cnv_valid ;
|
|
reg cnv_valid_t ;
|
|
reg cnv_valid_tt ;
|
|
reg cnv_cover_valid ;
|
|
reg cnv_cover_valid_t ;
|
|
reg cnv_cover_valid_tt ;
|
|
reg [ 6-1:0] cnv_channel ;
|
|
reg [ 6-1:0] cnv_channel_t ;
|
|
reg [ 6-1:0] cnv_channel_tt ;
|
|
|
|
reg monitor_flag ;
|
|
reg monitor_flag_t ;
|
|
reg monitor_flag_tt ;
|
|
|
|
reg [32-1:0] spi_din_r ;
|
|
|
|
wire spi_rdy ;
|
|
wire spi_start ;
|
|
wire [32-1:0] spi_din ;
|
|
wire spi_done ;
|
|
wire [32-1:0] spi_dout ;
|
|
|
|
//*****************************************************************************
|
|
// Instantiation
|
|
//*****************************************************************************
|
|
spi_full_duplex_master#
|
|
(
|
|
.CLK_DIV ( SPI_CLK_DIV ),
|
|
.DATA_WIDTH ( SPI_DATA_WIDTH )
|
|
)
|
|
u_spi_full_duplex_master
|
|
(
|
|
.clk ( clk ),
|
|
.rst_n ( rst_n ),
|
|
|
|
.rdy ( spi_rdy ),
|
|
.start ( spi_start ),
|
|
.din ( spi_din ),
|
|
.done ( spi_done ),
|
|
.dout ( spi_dout ),
|
|
|
|
.cs ( cs ),
|
|
.sclk ( sclk ),
|
|
.mosi ( mosi ),
|
|
.miso ( miso )
|
|
);
|
|
|
|
//*****************************************************************************
|
|
// Procedural blocks
|
|
//*****************************************************************************
|
|
|
|
//direct spi
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
spi_cmd_ready <= 1'b0;
|
|
end else if ( spi_cmd_valid && spi_rdy ) begin
|
|
spi_cmd_ready <= 1'b1;
|
|
end else begin
|
|
spi_cmd_ready <= 1'b0;
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
spi_data <= 0;
|
|
spi_data_en <= 1'b0;
|
|
end else if ( spi_cmd_valid && spi_rdy ) begin
|
|
spi_data <= spi_cmd_data;
|
|
spi_data_en <= 1'b1;
|
|
end else begin
|
|
spi_data_en <= 1'b0;
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
spi_flag <= 1'b0;
|
|
end else if ( spi_cmd_valid && spi_rdy ) begin
|
|
spi_flag <= 1'b1;
|
|
end else if ( spi_done ) begin
|
|
spi_flag <= 1'b0;
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
spi_res_en <= 1'b0;
|
|
spi_res <= 0;
|
|
end else if ( spi_flag && spi_done ) begin
|
|
spi_res_en <= 1'b1;
|
|
spi_res <= spi_dout;
|
|
end else begin
|
|
spi_res_en <= 1'b0;
|
|
end
|
|
end
|
|
|
|
//transmit
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
s_axis_trans_tready <= 1'b0;
|
|
end else if ( trans_pulse ) begin
|
|
s_axis_trans_tready <= 1'b1;
|
|
end else begin
|
|
s_axis_trans_tready <= 1'b0;
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
trans_data <= 0;
|
|
trans_data_en <= 1'b0;
|
|
end else if ( s_axis_trans_tvalid && s_axis_trans_tready && (~is_empty_cmd) ) begin
|
|
trans_data <= (is_stim_cmd)? stim_cmd:s_axis_trans_tdata;
|
|
trans_data_en <= 1'b1;
|
|
end else begin
|
|
trans_data_en <= 1'b0;
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
stim_state <= 0;
|
|
end else if ( trans_data[31:30]==2'b10 && trans_data[23:16]==8'd42 ) begin
|
|
stim_state <= trans_data[15:0];
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n )
|
|
stim_stage_code <= 0;
|
|
else if ( s_axis_trans_tvalid && s_axis_trans_tready && is_stim_cmd )
|
|
stim_stage_code <= 32'h3E7 + s_axis_trans_tdata[23:20];
|
|
end
|
|
|
|
//record flag
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
cnv_valid <= 1'b0;
|
|
end else if ( s_axis_trans_tvalid && s_axis_trans_tready ) begin
|
|
cnv_valid <= (is_cnv_cmd)? 1'b1:(is_empty_cmd? cnv_valid:1'b0);
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
cnv_cover_valid <= 1'b0;
|
|
end else if ( s_axis_trans_tvalid && s_axis_trans_tready ) begin
|
|
cnv_cover_valid <= (is_cover_cmd)? 1'b1:1'b0;
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
cnv_channel <= 1'b0;
|
|
end else if ( s_axis_trans_tvalid && s_axis_trans_tready ) begin
|
|
cnv_channel <= (is_cnv_cmd || is_cover_cmd)? {2'b00, s_axis_trans_tdata[19:16]}:cnv_channel;
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
cnv_valid_t <= 1'b0;
|
|
cnv_valid_tt <= 1'b0;
|
|
cnv_channel_t <= 0;
|
|
cnv_channel_tt <= 0;
|
|
cnv_cover_valid_t <= 1'b0;
|
|
cnv_cover_valid_tt <= 1'b0;
|
|
end else if ( spi_done ) begin
|
|
cnv_valid_t <= cnv_valid;
|
|
cnv_valid_tt <= cnv_valid_t;
|
|
cnv_channel_t <= cnv_channel;
|
|
cnv_channel_tt <= cnv_channel_t;
|
|
cnv_cover_valid_t <= cnv_cover_valid;
|
|
cnv_cover_valid_tt <= cnv_cover_valid_t;
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
cnv_res_tdata <= 0;
|
|
cnv_res_tvalid <= 1'b0;
|
|
end else if ( spi_done && (cnv_valid_tt || cnv_cover_valid_tt) ) begin
|
|
cnv_res_tdata <= cnv_valid_tt?
|
|
{spi_dout[31:16], cnv_channel_tt, spi_dout[9:1], 1'b0}:
|
|
{16'd0, cnv_channel_tt, 9'd0, 1'b1};
|
|
cnv_res_tvalid <= 1'b1;
|
|
end else begin
|
|
cnv_res_tvalid <= 1'b0;
|
|
end
|
|
end
|
|
|
|
//monitor
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
monitor_flag <= 1'b0;
|
|
end else if ( s_axis_trans_tvalid && s_axis_trans_tready ) begin
|
|
monitor_flag <= (is_mon_cmd)? 1'b1:(is_empty_cmd? monitor_flag:1'b0);
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
monitor_flag_t <= 1'b0;
|
|
monitor_flag_tt <= 1'b0;
|
|
end else if ( spi_done ) begin
|
|
monitor_flag_t <= monitor_flag;
|
|
monitor_flag_tt <= monitor_flag_t;
|
|
end
|
|
end
|
|
|
|
always @ ( posedge clk or negedge rst_n ) begin
|
|
if ( !rst_n ) begin
|
|
monitor_data <= 0;
|
|
monitor_data_en <= 1'b0;
|
|
end else if ( spi_done && monitor_flag_tt ) begin
|
|
monitor_data <= spi_dout[15:0];
|
|
monitor_data_en <= 1'b1;
|
|
end else begin
|
|
monitor_data_en <= 1'b0;
|
|
end
|
|
end
|
|
|
|
//spi control
|
|
always@( * ) begin
|
|
if ( !rst_n )
|
|
spi_din_r <= 0;
|
|
else if (spi_data_en)
|
|
spi_din_r <= spi_data;
|
|
else if (trans_data_en)
|
|
spi_din_r <= trans_data;
|
|
else
|
|
spi_din_r <= spi_din_r;
|
|
end
|
|
|
|
//*****************************************************************************
|
|
// Wire assignment
|
|
//*****************************************************************************
|
|
assign is_empty_cmd = (s_axis_trans_tdata[31:30]==CMD_EXTEND && s_axis_trans_tdata[24]==1'b0)? 1'b1:1'b0;
|
|
assign is_stim_cmd = (s_axis_trans_tdata[31:30]==CMD_EXTEND && s_axis_trans_tdata[24]==1'b1)? 1'b1:1'b0;
|
|
assign is_cover_cmd = (s_axis_trans_tdata[31:30]==CMD_EXTEND && s_axis_trans_tdata[25:24]==2'b11)? 1'b1:1'b0;
|
|
assign is_cnv_cmd = (s_axis_trans_tdata[31:30]==CMD_CONVERT)? 1'b1:1'b0;
|
|
assign is_mon_cmd = (s_axis_trans_tdata[31:30]==CMD_READ && s_axis_trans_tdata[23:16]==REG_ADDR_MONITOR)? 1'b1:1'b0;
|
|
|
|
assign stim_pol = s_axis_trans_tdata[26];
|
|
assign stim_ch = s_axis_trans_tdata[19:16];
|
|
assign stim_reg_addr= stim_pol? (REG_ADDR_NEG_CUR+stim_ch):(REG_ADDR_POS_CUR+stim_ch);
|
|
assign stim_cmd = {CMD_WRITE, s_axis_trans_tdata[29:28],4'h0,stim_reg_addr,s_axis_trans_tdata[15:0]};
|
|
|
|
assign spi_start = trans_data_en || spi_data_en;
|
|
assign spi_din = spi_din_r;
|
|
assign cnv_res_tlast = 1'b0;
|
|
|
|
endmodule
|