`timescale 1 ns / 1 ps module sine_gen# ( parameter CLK_PERIOD = 20 ) ( input clk , input rst_n , input phase_enable , input [32*16-1:0] phase_inc_array , input [32*16-1:0] phase_off_array , // input [ 8*16-1:0] magnitude_array , input dds_aclken , input dds_aresetn , input update , output [ 9*16-1:0] sine_wave_array ); //***************************************************************************** // localparam definition //***************************************************************************** localparam IDLE = 8'd0 ; localparam TRANS_ST = 8'd1 ; //***************************************************************************** // Internal register and wire declarations //***************************************************************************** reg [ 4-1:0] cstate ; reg [ 4-1:0] nstate ; wire [32-1:0] phase_inc[0:16-1] ; wire [32-1:0] phase_off[0:16-1] ; reg [ 4-1:0] cnt ; reg [ 4-1:0] ch ; reg s_axis_config_tvalid ; wire [64-1:0] s_axis_config_tdata ; reg s_axis_config_tlast ; reg aclken ; reg [ 2-1:0] aresetn_v ; wire aresetn ; wire m_axis_data_tvalid ; wire [16-1:0] m_axis_data_tdata ; wire m_axis_phase_tvalid ; wire [32-1:0] m_axis_phase_tdata ; wire event_s_config_tlast_missing ; wire event_s_config_tlast_unexpected ; reg [ 9-1:0] sine_data[0:16-1]; wire [ 9-1:0] sine_data_abs[0:16-1] ; reg [ 9-1:0] data[0:16-1] ; //***************************************************************************** // Instantiation //***************************************************************************** dds_stim_16ch u_dds_stim_16ch ( .aclk ( clk ), .aclken ( aclken ), .aresetn ( aresetn ), //Must be asserted for a minimum of 2 cycles .s_axis_config_tvalid ( s_axis_config_tvalid ), .s_axis_config_tdata ( s_axis_config_tdata ), .s_axis_config_tlast ( s_axis_config_tlast ), .m_axis_data_tvalid ( m_axis_data_tvalid ), .m_axis_data_tdata ( m_axis_data_tdata ), .m_axis_phase_tvalid ( m_axis_phase_tvalid ), .m_axis_phase_tdata ( m_axis_phase_tdata ), .event_s_config_tlast_missing ( event_s_config_tlast_missing ), .event_s_config_tlast_unexpected ( event_s_config_tlast_unexpected ) ); //***************************************************************************** always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) begin aclken <= 1'b0; aresetn_v <= 2'b11; end else begin aclken <= dds_aclken; aresetn_v <= {aresetn_v[0], dds_aresetn}; end end always@( posedge clk or negedge rst_n ) begin if( !rst_n ) cstate <= IDLE; else cstate <= nstate; end always@( * ) begin case ( cstate ) IDLE: if ( phase_enable ) nstate <= TRANS_ST; else nstate <= IDLE; TRANS_ST: if ( cnt == 4'hF ) nstate <= IDLE; else nstate <= TRANS_ST; default: nstate <= IDLE; endcase end always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) cnt <= 0; else if ( s_axis_config_tvalid ) cnt <= cnt + 1'b1; else cnt <= 0; end always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) s_axis_config_tvalid <= 1'b0; else if ( (cstate == TRANS_ST) && nstate == TRANS_ST ) s_axis_config_tvalid <= 1'b1; else s_axis_config_tvalid <= 1'b0; end assign s_axis_config_tdata = {phase_off[cnt],phase_inc[cnt]}; always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) s_axis_config_tlast <= 1'b0; else if ( cnt == 4'hE ) s_axis_config_tlast <= 1'b1; else s_axis_config_tlast <= 1'b0; end always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) ch <= 0; else if ( m_axis_data_tvalid ) ch <= ch + 1'b1; else ch <= 0; end always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) begin sine_data[ 0] <= 0; sine_data[ 1] <= 0; sine_data[ 2] <= 0; sine_data[ 3] <= 0; sine_data[ 4] <= 0; sine_data[ 5] <= 0; sine_data[ 6] <= 0; sine_data[ 7] <= 0; sine_data[ 8] <= 0; sine_data[ 9] <= 0; sine_data[10] <= 0; sine_data[11] <= 0; sine_data[12] <= 0; sine_data[13] <= 0; sine_data[14] <= 0; sine_data[15] <= 0; end else if ( m_axis_data_tvalid ) sine_data[ch] <= m_axis_data_tdata[8:0]; end integer j; always @ ( posedge clk or negedge rst_n ) begin if ( !rst_n ) for(j=0;j<16;j=j+1)begin data[j] <= 0; end else if ( !aresetn ) for(j=0;j<16;j=j+1)begin data[j] <= 0; end else if ( update ) for(j=0;j<16;j=j+1)begin data[j] <= sine_data[j][8]? {1'b1,sine_data_abs[j][7:0]}:sine_data[j]; end end //***************************************************************************** // Wire assignment //***************************************************************************** assign aresetn = (aresetn_v==2'b11)? 1'b1:1'b0; genvar i; generate for(i=0;i<16;i=i+1) begin : unpack assign phase_inc[i] = phase_inc_array[32*i+31 : 32*i]; assign phase_off[i] = phase_off_array[32*i+31 : 32*i]; end endgenerate generate for(i=0;i<16;i=i+1) begin : abs assign sine_data_abs[i] = ~(sine_data[i][8:0]-1'b1); end endgenerate generate for(i=0;i<16;i=i+1) begin : pack assign sine_wave_array[9*i+8 : 9*i] = data[i]; end endgenerate endmodule