`timescale 1 ns / 1 ps module trans_arrange# ( parameter CMD_CNV = 2'b00, parameter CMD_EXTEND = 2'b01, parameter CMD_WRITE = 2'b10, parameter CMD_READ = 2'b11, parameter REG_ADDR_STIM_POL = 8'd44 , parameter REG_ADDR_POS_CUR = 8'd64 , parameter REG_ADDR_NEG_CUR = 8'd96 ) ( input clk , input rst_n , input [16* 8-1:0] stim_trim_p_array , input [16* 8-1:0] stim_trim_n_array , input [16*9-1:0] sine_wave_array , input trans_round , //-------------------------------------------------- input input [ 32-1:0] s_axi_cmd_tdata , input s_axi_cmd_tlast , output reg s_axi_cmd_tready , input s_axi_cmd_tvalid , //-------------------------------------------------- output output reg [ 32-1:0] m_axi_trans_tdata , output reg m_axi_trans_tlast , input m_axi_trans_tready , output reg m_axi_trans_tvalid ); //***************************************************************************** // localparam definition //***************************************************************************** localparam RX_ST = 4'd0 ; localparam DECODE_ST = 4'd1 ; localparam FILL_ST = 4'd2 ; localparam POL_ST = 4'd3 ; localparam SEND_ST = 4'd4 ; //***************************************************************************** // Internal register and wire declarations //***************************************************************************** reg [ 4-1:0] cstate ; reg [ 4-1:0] nstate ; wire [ 9-1:0] sine_wave[0:15] ; wire [ 8-1:0] stim_trim_p[0:15] ; wire [ 8-1:0] stim_trim_n[0:15] ; reg [32-1:0] stim_rx ; reg is_tlast ; reg ce ; reg [16-1:0] polarity_mark ; wire is_pol_cmd ; wire is_empty_cmd ; wire is_stim_cmd ; wire is_sine ; wire cnv_is_cover ; wire [ 4-1:0] stim_ch ; wire [ 7-1:0] sine_ch ; wire [ 9-1:0] gain_c ; wire [ 9-1:0] stim_data ; wire [ 8-1:0] stim_abs ; wire [ 8-1:0] magnitude ; wire stim_pol ; wire [ 8-1:0] stim_mag ; wire [ 8-1:0] current_trim ; //***************************************************************************** // Instantiation //***************************************************************************** mult_gen_au8_bu9_p8 u_mult_gain ( .CLK ( clk ), .A ( stim_abs ), // input wire [7: 0] A .B ( gain_c ), // input wire [8: 0] B .CE ( ce ), .P ( magnitude ) // output wire [7: 0] P ); //***************************************************************************** always@( posedge clk or negedge rst_n ) begin if( !rst_n ) cstate <= RX_ST; else cstate <= nstate; end always@( * ) begin case ( cstate ) RX_ST: if ( s_axi_cmd_tready && s_axi_cmd_tvalid ) nstate <= DECODE_ST; else nstate <= RX_ST; DECODE_ST: if ( is_stim_cmd ) nstate <= FILL_ST; else if ( is_pol_cmd ) nstate <= POL_ST; else nstate <= SEND_ST; FILL_ST: nstate <= SEND_ST; POL_ST: nstate <= SEND_ST; SEND_ST: if ( m_axi_trans_tready && m_axi_trans_tvalid ) nstate <= RX_ST; else nstate <= SEND_ST; default: nstate <= RX_ST; endcase end //reve always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) s_axi_cmd_tready <= 1'b0; else if ( nstate == RX_ST ) s_axi_cmd_tready <= 1'b1; else s_axi_cmd_tready <= 1'b0; end always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) begin stim_rx <= 0; is_tlast <= 1'b0; end else if ( s_axi_cmd_tready && s_axi_cmd_tvalid ) begin stim_rx <= s_axi_cmd_tdata; is_tlast <= s_axi_cmd_tlast; end end //stim always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) polarity_mark <= 0; else if ( trans_round ) polarity_mark <= 0; else if ( (cstate == FILL_ST) && stim_pol) polarity_mark <= polarity_mark | (16'h0001 << stim_ch); end always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) ce <= 1'b0; else if ( cstate == RX_ST && nstate == DECODE_ST ) ce <= 1'b1; else ce <= 1'b0; end //transmit always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) begin m_axi_trans_tvalid <= 1'b0; m_axi_trans_tdata <= 0; m_axi_trans_tlast <= 1'b0; end else if ( m_axi_trans_tready && m_axi_trans_tvalid ) begin m_axi_trans_tvalid <= 1'b0; end else if ( nstate == SEND_ST && cstate == DECODE_ST ) begin m_axi_trans_tvalid <= 1'b1; m_axi_trans_tdata <= (is_empty_cmd)? 32'h40000000 : stim_rx; m_axi_trans_tlast <= is_tlast; end else if ( nstate == SEND_ST && cstate == FILL_ST ) begin m_axi_trans_tvalid <= 1'b1; m_axi_trans_tdata <= {2'b01, 2'b00, 1'b0, stim_pol, cnv_is_cover, 1'b1, stim_rx[23:16], current_trim, stim_mag}; m_axi_trans_tlast <= is_tlast; end else if ( nstate == SEND_ST && cstate == POL_ST ) begin m_axi_trans_tvalid <= 1'b1; m_axi_trans_tdata <= {2'b10, stim_rx[29:24], REG_ADDR_STIM_POL, stim_rx[15:0] | polarity_mark}; m_axi_trans_tlast <= is_tlast; end end //***************************************************************************** // Wire assignment //***************************************************************************** genvar i; generate for(i=0;i<16;i=i+1) begin : unpack assign sine_wave[i] = sine_wave_array[9*i+8 : 9*i]; end endgenerate generate for(i=0;i<16;i=i+1) begin : unpack_trim assign stim_trim_p[i] = stim_trim_p_array[8*i+7 : 8*i]; assign stim_trim_n[i] = stim_trim_n_array[8*i+7 : 8*i]; end endgenerate assign is_pol_cmd = (stim_rx[31:30]==CMD_WRITE && stim_rx[23:16]==REG_ADDR_STIM_POL)? 1'b1:1'b0; assign is_empty_cmd = (stim_rx[31:30]==CMD_EXTEND && stim_rx[23:20]==4'h0)? 1'b1:1'b0; assign is_stim_cmd = (stim_rx[31:30]==CMD_EXTEND && stim_rx[23:20]!=4'h0)? 1'b1:1'b0; assign is_sine = (stim_rx[31:30]==CMD_EXTEND && stim_rx[29]==1'b0)? 1'b1:1'b0; assign cnv_is_cover = (stim_rx[31:30]==CMD_EXTEND && stim_rx[28]==1'b1)? 1'b1:1'b0; assign stim_ch = stim_rx[19:16]; assign sine_ch = stim_rx[15: 9]; assign gain_c = stim_rx[ 8: 0]; assign stim_data = sine_wave[sine_ch]; assign stim_abs = stim_data[7:0]; assign stim_pol = (is_sine)? (~stim_data[8]):stim_rx[8]; assign stim_mag = (is_sine)? magnitude:stim_rx[7:0]; assign current_trim = stim_pol? (stim_trim_p[stim_ch]):(stim_trim_n[stim_ch]); endmodule