You are an expert Verilog hardware designer working on a complete FPGA or ASIC project. You are given the full source code of a Verilog project. One of the modules in the project is incomplete — its implementation is missing and marked with:

// >>> Module Implementation Begin

// <<< Module Implementation End

Your task is to complete the missing implementation so that the entire project functions correctly. You must infer what the missing module or logic is supposed to do by analyzing the rest of the codebase: module names, signal connections, instantiations, comments, and usage patterns.

Follow these rules:

1. Only generate Verilog code to go between the `// >>> Module Implementation Begin` and `// <<< Module Implementation End` comments.
2. Use Verilog-2001 syntax. Ensure the code is synthesizable.
3. Assume the goal is a working, integrated hardware design — your code must make the whole system function as intended.
4. Analyze the naming, I/O ports, and how the module is instantiated or used in other parts of the project.
5. Implement correct behavior based on design context. Do not guess randomly — reason it out.
6. Avoid vendor-specific features unless explicitly required.
7. Do not output comments, explanation, or anything outside the required code region unless explicitly asked.

Your output should contain **only the Verilog code** that fits inside the marked region.

/*
 * Copyright (c) 2024 Your Name
 * SPDX-License-Identifier: Apache-2.0
 */

`default_nettype none

module tt_um_synth_simple_mm (
//module synth_simple (
    input  wire [7:0] ui_in,    // Dedicated inputs
    output wire [7:0] uo_out,   // Dedicated outputs
    input  wire [7:0] uio_in,   // IOs: Input path
    output wire [7:0] uio_out,  // IOs: Output path
    output wire [7:0] uio_oe,   // IOs: Enable path (active high: 0=input, 1=output)
    input  wire       ena,      // always 1 when the design is powered, so you can ignore it
    input  wire       clk,      // clock
    input  wire       rst_n     // reset_n - low to reset
);

  // All output pins must be assigned. If not used, assign to 0.
  //assign uo_out  = ui_in + uio_in;  // Example: ou_out is the sum of ui_in and uio_in
  assign uio_out = 0;
  //assign uio_oe  = 0;

  // List all unused inputs to prevent warnings
  //wire _unused = &{ena, clk, rst_n, 1'b0};
  wire _unused = &{ena, ui_in[7:5], 1'b0};	

  wire [4:0] note_enn_i;
  wire pwm_out_i;
  wire pwm_out_left;
  reg pwm_out_right;  
    
  // set all IOs as inputs
  assign uio_oe = 8'b0;   
  // use 5 out of 8 input
  assign note_enn_i = ui_in[4:0];  
  // synth module  
       synth_module_v #(
           .nnotes(5),
           .nswitches(8)
       ) sm_i (
           .clk(clk),
           .rstn(rst_n),
           .sw(uio_in),
           .note_enn(note_enn_i),
           .pwm_out(pwm_out_i)
		      );

    assign pwm_out_left = pwm_out_i;

    always @ (  posedge clk or negedge rst_n)
     begin
         if ( rst_n == 1'b0 ) 
          begin
             pwm_out_right <= 0;
          end
        else
          begin 
             pwm_out_right <= pwm_out_i;
          end
     end // always @ (  posedge clk or negedge rstn)

    assign uo_out = {6'b0, pwm_out_right, pwm_out_left};

endmodule


module synth_module_v(
		      clk,
		      rstn,
		      sw,
		      note_enn,
		      pwm_out
		      );
   parameter [31:0]nnotes  = 5;
   parameter [31:0]nswitches  = 8;
   
   input clk;
   input rstn;
   input [( nswitches - 1 ):0] sw;
   input [( nnotes - 1 ):0]    note_enn;
   output 		       pwm_out;
   
   //localparam debug_mode  = 0;

   localparam nbit_wav_in  = 6;
   //localparam nbit_bar  = 4;
   //localparam nbit_adsr_idx  = 4;
   //localparam max_adsr_idx  = 14;
   localparam nbit_sample  = 8;
   localparam nbit_notes = 7;   
   
   localparam [7:0] cpwm_period  = ( 2 ** 8 ) - 1;

   localparam signed [7:0] cpwm_offset  = 8'd127;   
   localparam [nbit_notes-1:0] cC0  = 57;   
   localparam [nbit_notes-1:0] cD0  = 59;   
   localparam [nbit_notes-1:0] cEb0 = 60;
   localparam [nbit_notes-1:0] cE0  = 61;   
   localparam [nbit_notes-1:0] cF0  = 62;
   localparam [nbit_notes-1:0] cGb0  = 63;
   localparam [nbit_notes-1:0] cG0  = 64;
   localparam [nbit_notes-1:0] cAb0  = 65;
   localparam [nbit_notes-1:0] cA0  = 66;
   localparam [nbit_notes-1:0] cBb0  = 67;
   localparam [nbit_notes-1:0] cB0  = 68;
   localparam [nbit_notes-1:0] cC1  = 69;

   wire [nbit_notes-1:0]       cCFG_Strangelove0[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_Strangelove1[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_Smoke_on_the_water[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_PMAJ[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_Oxygene0[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_Oxygene1[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_Oxygene2[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_Wake_me_up_Fix_you[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_The_final_countdown0[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_The_final_countdown1[0:nnotes-1];         
   wire [nbit_notes-1:0]       cCFG_Dont_go1[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_FC[0:nnotes-1];    
   wire [nbit_notes-1:0]       cCFG_Knocking_at_your_back_door0[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_Knocking_at_your_back_door1[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_MAJ[0:nnotes-1];
   wire [nbit_notes-1:0]       cCFG_CG[0:nnotes-1];                 

   wire [3:0] 		       snotes_sel;
   localparam min_adsr_lev_idx  = 0;
   localparam max_adsr_lev_idx  = 10;

   wire [nbit_wav_in-1:0]      cadsr_sus_levels[min_adsr_lev_idx:max_adsr_lev_idx];   
   
   wire [( nnotes - 1 ):0]     snote_en;
   wire [( nnotes - 1 ):0]     snote_en_one_hot;   
   wire [1:0] 		       swave_sel;
   //localparam cadsr_a_t_idx0  = 0;
   //localparam cadsr_d_t_idx0  = 0;
   //localparam cadsr_r_t_idx0  = 0;
   //localparam cadsr_a_t_idx1  = 0;
   //localparam cadsr_d_t_idx1  = 10;
   //localparam cadsr_r_t_idx1  = 0;
   //localparam cadsr_a_t_idx2  = 10;
   //localparam cadsr_d_t_idx2  = 0;
   //localparam cadsr_r_t_idx2  = 0;
   //localparam cadsr_a_t_idx3  = 10;
   //localparam cadsr_d_t_idx3  = 10;
   //localparam cadsr_r_t_idx3  = 0;
   wire [1:0] 		       sadsr_sel;
   wire [5:0] 		       sadsr_value;
   wire 		       sadsr_vout;
   wire 		       sclick_enable;
   wire [7:0] 		       ssynth_out;
   wire 		       spwm_clear;
   reg [( nswitches - 1 ):0]   ssw_reg[2:0];
   reg [( nnotes - 1 ):0]      snote_synch[2:0];
   
   reg [nbit_notes-1:0]        snotes[0:nnotes-1];
   wire [6:0] 		       sper_adx;   

   wire 		       sper_adx_valid;   
   reg [2:0] 		       snote_idx;   
   reg [3:0] 		       sadsr_a_t_idx;
   reg [3:0] 		       sadsr_d_t_idx;
   reg [5:0] 		       sadsr_s_level;
   reg [3:0] 		       sadsr_r_t_idx;
   reg signed [7:0] 	       ssynth_out_adsr;
   reg [7:0] 		       scnt_pwm;
   reg 			       scnt_pwm_tc;
   reg [7:0] 		       scnt_pwm_on;
   reg 			       scnt_pwm_on_en;

   reg 			       pwm_out;

   assign cadsr_sus_levels[0] = 0;
   assign cadsr_sus_levels[1] = 6;
   assign cadsr_sus_levels[2] = 13;
   assign cadsr_sus_levels[3] = 19;
   assign cadsr_sus_levels[4] = 25;
   assign cadsr_sus_levels[5] = 32;
   assign cadsr_sus_levels[6] = 38;
   assign cadsr_sus_levels[7] = 44;
   assign cadsr_sus_levels[8] = 50;
   assign cadsr_sus_levels[9] = 57;
   assign cadsr_sus_levels[10] = 63;

   assign cCFG_Strangelove0[0]=cC0;
   assign cCFG_Strangelove0[1]=cEb0;
   assign cCFG_Strangelove0[2]=cF0;
   assign cCFG_Strangelove0[3]=cG0;
   assign cCFG_Strangelove0[4]=cBb0;

   assign cCFG_Strangelove1[0]=cC0;
   assign cCFG_Strangelove1[1]=cD0;
   assign cCFG_Strangelove1[2]=cEb0;
   assign cCFG_Strangelove1[3]=cF0;
   assign cCFG_Strangelove1[4]=cAb0;

   assign cCFG_Smoke_on_the_water[0]=cD0;
   assign cCFG_Smoke_on_the_water[1]=cE0;
   assign cCFG_Smoke_on_the_water[2]=cF0;
   assign cCFG_Smoke_on_the_water[3]=cG0;
   assign cCFG_Smoke_on_the_water[4]=cAb0;

   assign cCFG_PMAJ[0]=cC0;
   assign cCFG_PMAJ[1]=cD0;
   assign cCFG_PMAJ[2]=cE0;
   assign cCFG_PMAJ[3]=cG0;
   assign cCFG_PMAJ[4]=cA0;

   assign cCFG_Oxygene0[0]=cC0;
   assign cCFG_Oxygene0[1]=cEb0;
   assign cCFG_Oxygene0[2]= cG0;
   assign cCFG_Oxygene0[3]=cBb0;
   assign cCFG_Oxygene0[4]= cC1;

   assign cCFG_Oxygene1[0]=cC0;
   assign cCFG_Oxygene1[1]=cD0;
   assign cCFG_Oxygene1[2]=cG0;
   assign cCFG_Oxygene1[3]=cA0;
   assign cCFG_Oxygene1[4]=cBb0;

   assign cCFG_Oxygene2[0]=cC0;
   assign cCFG_Oxygene2[1]=cEb0;
   assign cCFG_Oxygene2[2]= cF0;
   assign cCFG_Oxygene2[3]=cG0;
   assign cCFG_Oxygene2[4]=cA0;

   assign cCFG_Wake_me_up_Fix_you[0]=cD0;
   assign cCFG_Wake_me_up_Fix_you[1]=cEb0;
   assign cCFG_Wake_me_up_Fix_you[2]= cG0;
   assign cCFG_Wake_me_up_Fix_you[3]=cAb0;
   assign cCFG_Wake_me_up_Fix_you[4]= cBb0;

   assign cCFG_The_final_countdown0[0]=cC0;
   assign cCFG_The_final_countdown0[1]=cEb0;
   assign cCFG_The_final_countdown0[2]= cF0;
   assign cCFG_The_final_countdown0[3]=cG0;
   assign cCFG_The_final_countdown0[4]=cAb0;

   assign cCFG_The_final_countdown1[0]=cC0;
   assign cCFG_The_final_countdown1[1]=cD0;
   assign cCFG_The_final_countdown1[2]=cEb0;
   assign cCFG_The_final_countdown1[3]= cF0;
   assign cCFG_The_final_countdown1[4]=cG0;

   assign cCFG_Dont_go1[0]=cEb0;
   assign cCFG_Dont_go1[1]= cF0;
   assign cCFG_Dont_go1[2]=cG0;
   assign cCFG_Dont_go1[3]=cAb0;
   assign cCFG_Dont_go1[4]= cC1;

   assign cCFG_FC[0]=cF0;
   assign cCFG_FC[1]=cG0;
   assign cCFG_FC[2]=cA0;
   assign cCFG_FC[3]=cB0;
   assign cCFG_FC[4]=cC1;

   assign cCFG_Knocking_at_your_back_door0[0]=cD0;
   assign cCFG_Knocking_at_your_back_door0[1]=cE0;
   assign cCFG_Knocking_at_your_back_door0[2]=cGb0;
   assign cCFG_Knocking_at_your_back_door0[3]= cG0;
   assign cCFG_Knocking_at_your_back_door0[4]=cA0;

   assign cCFG_Knocking_at_your_back_door1[0]=cC0;
   assign cCFG_Knocking_at_your_back_door1[1]=cD0;
   assign cCFG_Knocking_at_your_back_door1[2]=cE0;
   assign cCFG_Knocking_at_your_back_door1[3]=cGb0;
   assign cCFG_Knocking_at_your_back_door1[4]= cG0;

   assign cCFG_MAJ[0]=cC0;
   assign cCFG_MAJ[1]=cE0;
   assign cCFG_MAJ[2]=cG0;
   assign cCFG_MAJ[3]=cB0;
   assign cCFG_MAJ[4]=cC1;

   assign cCFG_CG[0]=cC0;
   assign cCFG_CG[1]=cD0;
   assign cCFG_CG[2]=cE0;
   assign cCFG_CG[3]=cF0;
   assign cCFG_CG[4]=cG0;
   
   assign sclick_enable = 1'b0;
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             ssw_reg[0] <= 0;
	     ssw_reg[1] <= 0;
	     ssw_reg[2] <= 0;	     
             snote_synch[0] <= 5'b1;
             snote_synch[1] <= 5'b1;
             snote_synch[2] <= 5'b1;	     	     
          end
        else
          begin 
             ssw_reg[0] <= sw;
	     ssw_reg[1] <= ssw_reg[0];
	     ssw_reg[2] <= ssw_reg[1];	     
             snote_synch[0] <= note_enn;
             snote_synch[1] <= snote_synch[0];
	     snote_synch[2] <= snote_synch[1];	     
          end
     end // always @ (  posedge clk or negedge rstn)
   
   assign swave_sel = ssw_reg[2][1:0];
   assign sadsr_sel = ssw_reg[2][3:2];
   assign snotes_sel = ssw_reg[2][7:4];
   assign snote_en =  ~( snote_synch[2]);   
   
   always @ (  snotes_sel)
     begin
        case (snotes_sel)
	  0 :
	    begin
	       snotes[0]<=cCFG_Strangelove0[0];
	       snotes[1]<=cCFG_Strangelove0[1];
	       snotes[2]<=cCFG_Strangelove0[2];
	       snotes[3]<=cCFG_Strangelove0[3];
	       snotes[4]<=cCFG_Strangelove0[4];
	    end
	  4 :
	    begin
	       snotes[0]<=cCFG_Strangelove1[0];
	       snotes[1]<=cCFG_Strangelove1[1];
	       snotes[2]<=cCFG_Strangelove1[2];
	       snotes[3]<=cCFG_Strangelove1[3];
	       snotes[4]<=cCFG_Strangelove1[4];
	    end
	  8 :
	    begin
	       snotes[0]<=cCFG_Smoke_on_the_water[0];
	       snotes[1]<=cCFG_Smoke_on_the_water[1];
	       snotes[2]<=cCFG_Smoke_on_the_water[2];
	       snotes[3]<=cCFG_Smoke_on_the_water[3];
	       snotes[4]<=cCFG_Smoke_on_the_water[4];
	    end
	  12 :
	    begin
	       snotes[0]<=cCFG_PMAJ[0];
	       snotes[1]<=cCFG_PMAJ[1];
	       snotes[2]<=cCFG_PMAJ[2];
	       snotes[3]<=cCFG_PMAJ[3];
	       snotes[4]<=cCFG_PMAJ[4];
	    end
	  1 :
	    begin
	       snotes[0]<=cCFG_Oxygene0[0];
	       snotes[1]<=cCFG_Oxygene0[1];
	       snotes[2]<=cCFG_Oxygene0[2];
	       snotes[3]<=cCFG_Oxygene0[3];
	       snotes[4]<=cCFG_Oxygene0[4];
	    end
	  5 :
	    begin
	       snotes[0]<=cCFG_Oxygene1[0];
	       snotes[1]<=cCFG_Oxygene1[1];
	       snotes[2]<=cCFG_Oxygene1[2];
	       snotes[3]<=cCFG_Oxygene1[3];
	       snotes[4]<=cCFG_Oxygene1[4];
	    end
	  9 :
	    begin
	       snotes[0]<=cCFG_Oxygene2[0];
	       snotes[1]<=cCFG_Oxygene2[1];
	       snotes[2]<=cCFG_Oxygene2[2];
	       snotes[3]<=cCFG_Oxygene2[3];
	       snotes[4]<=cCFG_Oxygene2[4];
	    end
	  13 :
	    begin
	       snotes[0]<=cCFG_Wake_me_up_Fix_you[0];
	       snotes[1]<=cCFG_Wake_me_up_Fix_you[1];
	       snotes[2]<=cCFG_Wake_me_up_Fix_you[2];
	       snotes[3]<=cCFG_Wake_me_up_Fix_you[3];
	       snotes[4]<=cCFG_Wake_me_up_Fix_you[4];
	    end
	  2 :
	    begin
	       snotes[0]<=cCFG_The_final_countdown0[0];
	       snotes[1]<=cCFG_The_final_countdown0[1];
	       snotes[2]<=cCFG_The_final_countdown0[2];
	       snotes[3]<=cCFG_The_final_countdown0[3];
	       snotes[4]<=cCFG_The_final_countdown0[4];
	    end
	  6 :
	    begin
	       snotes[0]<=cCFG_The_final_countdown1[0];
	       snotes[1]<=cCFG_The_final_countdown1[1];
	       snotes[2]<=cCFG_The_final_countdown1[2];
	       snotes[3]<=cCFG_The_final_countdown1[3];
	       snotes[4]<=cCFG_The_final_countdown1[4];
	    end
	  10 :
	    begin
	       snotes[0]<=cCFG_Dont_go1[0];
	       snotes[1]<=cCFG_Dont_go1[1];
	       snotes[2]<=cCFG_Dont_go1[2];
	       snotes[3]<=cCFG_Dont_go1[3];
	       snotes[4]<=cCFG_Dont_go1[4];
	    end
	  14 :
	    begin
	       snotes[0]<=cCFG_FC[0];
	       snotes[1]<=cCFG_FC[1];
	       snotes[2]<=cCFG_FC[2];
	       snotes[3]<=cCFG_FC[3];
	       snotes[4]<=cCFG_FC[4];
	    end
	  3 :
	    begin
	       snotes[0]<=cCFG_Knocking_at_your_back_door0[0];
	       snotes[1]<=cCFG_Knocking_at_your_back_door0[1];
	       snotes[2]<=cCFG_Knocking_at_your_back_door0[2];
	       snotes[3]<=cCFG_Knocking_at_your_back_door0[3];
	       snotes[4]<=cCFG_Knocking_at_your_back_door0[4];
	    end
	  7 :
	    begin
	       snotes[0]<=cCFG_Knocking_at_your_back_door1[0];
	       snotes[1]<=cCFG_Knocking_at_your_back_door1[1];
	       snotes[2]<=cCFG_Knocking_at_your_back_door1[2];
	       snotes[3]<=cCFG_Knocking_at_your_back_door1[3];
	       snotes[4]<=cCFG_Knocking_at_your_back_door1[4];
	    end
	  11 :
	    begin
	       snotes[0]<=cCFG_MAJ[0];
	       snotes[1]<=cCFG_MAJ[1];
	       snotes[2]<=cCFG_MAJ[2];
	       snotes[3]<=cCFG_MAJ[3];
	       snotes[4]<=cCFG_MAJ[4];
	    end
	  15 :
	    begin
	       snotes[0]<=cCFG_CG[0];
	       snotes[1]<=cCFG_CG[1];
	       snotes[2]<=cCFG_CG[2];
	       snotes[3]<=cCFG_CG[3];
	       snotes[4]<=cCFG_CG[4];
	    end	  
        endcase
     end // always @ (  snotes_sel)

   assign sper_adx_valid = snote_en[0] | snote_en[1] | snote_en[2] | snote_en[3] | snote_en[4];
   
   assign snote_en_one_hot[0] = snote_en[0];
   assign snote_en_one_hot[1] = snote_en[1] & ~snote_en_one_hot[0];
   assign snote_en_one_hot[2] = snote_en[2] & ~snote_en_one_hot[1];
   assign snote_en_one_hot[3] = snote_en[3] & ~snote_en_one_hot[2];
   assign snote_en_one_hot[4] = snote_en[4] & ~snote_en_one_hot[3];   
   
   always @ ( snote_en_one_hot )
     begin
	case (snote_en_one_hot)
	  5'b10000:
	    snote_idx <= 3'd4;
	  5'b01000:
	    snote_idx <= 3'd3;
	  5'b00100:
	    snote_idx <= 3'd2;
	  5'b00010:
	    snote_idx <= 3'd1;
	  default :
	    snote_idx <= 3'd0;
	endcase // case (snote_en_one_hot)
     end
   
   assign sper_adx = snotes[snote_idx];   
   
   always @ (  sadsr_sel)
     begin
        case ( sadsr_sel ) 
          2'b00:
            begin
               sadsr_a_t_idx <= 0;	   
               sadsr_d_t_idx <= 0;	   
               sadsr_s_level <= cadsr_sus_levels[10];
               sadsr_r_t_idx <= 0;	   
            end
          2'b01:
            begin
               sadsr_a_t_idx <= 0;	   
               sadsr_d_t_idx <= 10;
               sadsr_s_level <= cadsr_sus_levels[0];
               sadsr_r_t_idx <= 0;	   
            end
          2'b10:
            begin
               sadsr_a_t_idx <= 10;
               sadsr_d_t_idx <= 0;	   
               sadsr_s_level <= cadsr_sus_levels[10];
               sadsr_r_t_idx <= 0;
            end
          2'b11:
            begin
               sadsr_a_t_idx <= 10;
               sadsr_d_t_idx <= 10;
               sadsr_s_level <= cadsr_sus_levels[0];
               sadsr_r_t_idx <= 0;	   
            end
        endcase
     end // always @ (  sadsr_sel)

	 
   adsr_v #(
            .nbit_data(6),
            .nbit_idx(4),
            .max_idx(14)
	    //.max_idx(10)
            ) adsr_i (
		      .a_t_idx(sadsr_a_t_idx),
		      .clk(clk),
		      .d_t_idx(sadsr_d_t_idx),
		      .r_t_idx(sadsr_r_t_idx),
		      .rstn(rstn),
		      .s_level(sadsr_s_level),
		      .vin(sper_adx_valid),
		      .dout(sadsr_value),
		      .vout(sadsr_vout)
		      );
	
   wav_gen_simple_v #(
		      //.debug_mode(0),
		      .nbit_freq_adx(7),
		      .nbit_wav_in(6),
		      .nbit_wav_out(8)
		      //.nbit_bar(4)
		      ) wav_gen_1 (
				   .click_en_in(sclick_enable),
				   .clk(clk),
				   .per_adx_in(sper_adx),
				   .per_adx_valid_in(sadsr_vout),
	   			   //.per_adx_valid_in(sper_adx_valid),
				   .rstn(rstn),
				   .wsel(swave_sel),
				   .wout(ssynth_out)
				   );
   
   always @ (  ssynth_out or  sadsr_value)
     begin : synth_with_adsr
        reg signed [nbit_sample+nbit_wav_in:0]tmp;
        tmp = ( $signed(ssynth_out) * $signed({1'b0, sadsr_value}) );	
        ssynth_out_adsr <= $signed(tmp[nbit_sample+nbit_wav_in-1:nbit_wav_in]);	
     end
   
   //assign ssynth_out_adsr = ssynth_out;
	
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             scnt_pwm <= 0;
          end
        else
          begin 
             if ( scnt_pwm_tc == 1'b1 ) 
               begin
                  scnt_pwm <= 0;		   
               end
             else
               begin 
                  scnt_pwm <= ( scnt_pwm + 1'b1 );
               end
          end
     end // always @ (  posedge clk or negedge rstn)
   
   always @ (  scnt_pwm)
     begin
        //if ( $unsigned(scnt_pwm) == $unsigned(( 2 ** 8 ) - 1 ) ) 
	if ( $unsigned(scnt_pwm) == $unsigned(cpwm_period) )
          begin
             scnt_pwm_tc <= 1'b1;
          end
        else
          begin 
             scnt_pwm_tc <= 1'b0;
          end
     end // always @ (  scnt_pwm)
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             scnt_pwm_on <= 0;	   
          end
        else
          begin 
             if ( scnt_pwm_tc == 1'b1 ) 
               begin
                  scnt_pwm_on <= $unsigned( ssynth_out_adsr + cpwm_offset );
               end
             else
               begin 
                  if ( scnt_pwm_on_en == 1'b1 ) 
                    begin
                       scnt_pwm_on <= ( scnt_pwm_on - 1'b1 );
                    end
               end
          end
     end // always @ (  posedge clk or negedge rstn)
   
   always  @ (scnt_pwm_on)
     begin
        if ( scnt_pwm_on != 0 ) 
          begin
             scnt_pwm_on_en <= 1'b1;
          end
        else
          begin 
             scnt_pwm_on_en <= 1'b0;
          end
     end // always  @ (scnt_pwm_on)
   
   assign spwm_clear =  ~( scnt_pwm_on_en);
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             pwm_out <= 1'b0;
          end
        else
          begin 
             if ( spwm_clear == 1'b1 ) 
               begin
                  pwm_out <= 1'b0;
               end
             else
               begin 
                  pwm_out <= 1'b1;
               end
          end
     end // always @ (  posedge clk or negedge rstn)
   
endmodule 


module adsr_v(
            clk,
            rstn,
            vin,
            a_t_idx,
            d_t_idx,
            s_level,
            r_t_idx,
            dout,
            vout
	    );
   
   parameter [31:0]nbit_data  = 6;
   parameter [31:0]nbit_idx  = 4;
   parameter [31:0]max_idx  = 14;
   
   input clk;
   input rstn;
   input vin;
   input [( nbit_idx - 1 ):0] a_t_idx;
   input [( nbit_idx - 1 ):0] d_t_idx;
   input [( nbit_data - 1 ):0] s_level;
   input [( nbit_idx - 1 ):0]  r_t_idx;
   output [( nbit_data - 1 ):0] dout;
   output 			vout;
   
   localparam cnbit_cnt  = 28;
   //localparam cnbit_cnt  = 24;
   localparam [cnbit_cnt-1:0] cstep_thr0  = 28'd190;
   //localparam [cnbit_cnt-1:0] cstep_thr0  = 24'd190;	
   
   localparam clog2_n_pwl  = 3;
   localparam [clog2_n_pwl-1:0] cn_pwl  = 7;
   localparam [clog2_n_pwl-1:0] cpwl_thr = cn_pwl - 1;
   
   localparam [nbit_data-1:0] cval_max  = ( ( 2 ** nbit_data ) - 1 );
   //localparam cval_min  = 0;   
   
   wire 			sattack_tc;
   wire 			sinit_cnt_from_attack;
   wire 			sinit_cnt_from_decay;
   wire 			sinit_cnt_from_release;
   reg [2:0] 			sstate;
   reg 				sis_idle;
   reg 				sis_attack;
   reg 				sis_decay;
   reg 				sis_sustain;
   reg 				sis_release;
   reg [27:0] 			scnt_step_thr0;
   
   reg [27:0] 			scnt_step_thri;
   reg [27:0] 			scnt_step;
   reg 				scnt_step_tc;
   reg [( nbit_data - 1 ):0] 	scnt_val;
   reg 				sdecay_tc;
   reg 				srelease_tc;
   reg 				scnt_val_tc;
   reg [clog2_n_pwl-1:0] 			scnt_pwl;
   reg 				scnt_pwl_tc;

   wire [cnbit_cnt-1:0] 		cstep_thr0_v [0:max_idx];   
   wire [nbit_data-1:0] 		cval_thr_v [0:cn_pwl-1];   

   assign cstep_thr0_v[0] = cstep_thr0;
   assign cstep_thr0_v[1] = {cstep_thr0_v[0][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[2] = {cstep_thr0_v[1][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[3] = {cstep_thr0_v[2][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[4] = {cstep_thr0_v[3][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[5] = {cstep_thr0_v[4][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[6] = {cstep_thr0_v[5][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[7] = {cstep_thr0_v[6][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[8] = {cstep_thr0_v[7][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[9] = {cstep_thr0_v[8][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[10] = {cstep_thr0_v[9][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[11] = {cstep_thr0_v[10][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[12] = {cstep_thr0_v[11][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[13] = {cstep_thr0_v[12][cnbit_cnt-2:0], 1'b1};
   assign cstep_thr0_v[14] = {cstep_thr0_v[13][cnbit_cnt-2:0], 1'b1};   
   
   assign cval_thr_v[0] = 15;
   assign cval_thr_v[1] = 39;
   assign cval_thr_v[2] = 51;
   assign cval_thr_v[3] = 59;      
   assign cval_thr_v[4] = 61;
   assign cval_thr_v[5] = 62;
   assign cval_thr_v[6] = 63;         
   
   /// FSM
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             sstate <= 3'b000;
          end
        else
          begin 
             case ( sstate ) 
               3'b000:
                 begin
                    if ( vin == 1'b1 ) 
                      begin
                         sstate <= 3'b001;
                      end
                 end
               3'b001:
                 begin
                    if ( vin == 1'b0 ) 
                      begin
                         sstate <= 3'b100;
                      end
                    else
                      begin 
                         if ( sattack_tc == 1'b1 ) 
                           begin
                              sstate <= 3'b010;
                           end
                      end
                 end
               3'b010:
                 begin
                    if ( vin == 1'b0 ) 
                      begin
                         sstate <= 3'b100;
                      end
                    else
                      begin 
                         if ( sdecay_tc == 1'b1 ) 
                           begin
                              sstate <= 3'b011;
                           end
                      end
                 end
               3'b011:
                 begin
                    if ( vin == 1'b0 ) 
                      begin
                         sstate <= 3'b100;
                      end
                 end
               3'b100:
                 begin
                    if ( vin == 1'b1 ) 
                      begin
                         sstate <= 3'b001;
                      end
                    else
                      begin 
                         if ( srelease_tc == 1'b1 ) 
                           begin
                              sstate <= 3'b000;
                           end
                      end
                 end
               default :
                 begin
                    sstate <= 3'b000;
                 end
             endcase
          end
     end // always @ (  posedge clk)

   /// FSM outputs
   
   always @ (  sstate)
     begin
        sis_idle <= 1'b0;
        sis_attack <= 1'b0;
        sis_decay <= 1'b0;
        sis_sustain <= 1'b0;
        sis_release <= 1'b0;
        case ( sstate ) 
          3'b000:
            begin
               sis_idle <= 1'b1;
            end
          3'b001:
            begin
               sis_attack <= 1'b1;
            end
          3'b010:
            begin
               sis_decay <= 1'b1;
            end
          3'b011:
            begin
               sis_sustain <= 1'b1;
            end
          3'b100:
            begin
               sis_release <= 1'b1;
            end
          default :
            begin
               sis_idle <= 1'b0;
               sis_attack <= 1'b0;
               sis_decay <= 1'b0;
               sis_sustain <= 1'b0;
               sis_release <= 1'b0;
            end
        endcase
     end // always @ (  sstate)
   
   assign sinit_cnt_from_attack = ( sis_attack &  ~( vin) );
   assign sinit_cnt_from_decay = ( sis_decay &  ~( vin) );
   assign sinit_cnt_from_release = ( sis_release & vin );
   
   always @ (  sis_idle or  sis_attack or  sis_decay or  sis_release or  a_t_idx or  d_t_idx or  r_t_idx)
     begin
        if ( sis_idle == 1'b1 ) 
          begin
             scnt_step_thr0 <= cstep_thr0_v[0];
          end
        else
          begin 
             if ( sis_attack == 1'b1 ) 
               begin
                  scnt_step_thr0 <= cstep_thr0_v[a_t_idx];
               end
             else
               begin 
                  if ( sis_decay == 1'b1 ) 
                    begin
                       scnt_step_thr0 <= cstep_thr0_v[d_t_idx];
                    end
                  else
                    begin 
                       if ( sis_release == 1'b1 ) 
			 begin
                            scnt_step_thr0 <= cstep_thr0_v[r_t_idx];
			 end
                       else
			 begin 
                            scnt_step_thr0 <= cstep_thr0_v[0];
			 end
                    end
               end
          end
     end // always @ (  sis_idle or  sis_attack or  sis_decay or  sis_release or  a_t_idx or  d_t_idx or  r_t_idx)
   
   always @ (  scnt_step_thr0 or  scnt_pwl)
     begin : cnt_step_threshold
	reg [cnbit_cnt-1:0] tmp [0:cn_pwl-1];
	
        integer 	    idx;
        tmp[0] = scnt_step_thr0;
        for ( idx = 1 ; ( idx <= 6 ) ; idx = ( idx + 1 ) )
          begin 
             tmp[idx] = { tmp[idx-1][cnbit_cnt-2:0], 1'b1 };
          end
        scnt_step_thri <= tmp[scnt_pwl];
     end
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             scnt_step <= 0;
          end
        else
          begin 
             if ( ( ( ( ( sis_idle == 1'b1 ) | ( sis_sustain == 1'b1 ) ) | ( sinit_cnt_from_attack == 1'b1 ) ) | ( sinit_cnt_from_decay == 1'b1 ) ) | ( sinit_cnt_from_release == 1'b1 ) ) 
               begin
                  scnt_step <= 0;
               end
             else
               begin 
                  if ( ( ( sis_attack == 1'b1 ) | ( sis_decay == 1'b1 ) ) | ( sis_release == 1'b1 ) ) 
                    begin
                       if ( scnt_step_tc == 1'b1 ) 
                         begin
                            scnt_step <= 0;
                         end
                       else
                         begin 
                            scnt_step <= ( scnt_step + 1'b1 );
                         end
                    end
               end
          end
     end // always @ (  posedge clk)
   
   always @ (  scnt_step or  scnt_step_thri)
     begin
        if ( scnt_step == scnt_step_thri ) 
          begin
             scnt_step_tc <= 1'b1;
          end
        else
          begin 
             scnt_step_tc <= 1'b0;
          end
     end // always @ (  scnt_step or  scnt_step_thri)
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             scnt_val <= 0;
          end
        else
          begin 
             if ( ( sis_idle == 1'b1 ) | ( sinit_cnt_from_release == 1'b1 ) ) 
               begin
                  scnt_val <= 0;
               end
             else
               begin 
                  if ( sis_attack == 1'b1 ) 
                    begin
                       if ( scnt_step_tc == 1'b1 ) 
                         begin
                            //if ( scnt_val < $unsigned(( 2 ** nbit_data ) - 1 ) ) 
				 if ( scnt_val < $unsigned(cval_max) ) 				 
                              begin
                                 scnt_val <= ( scnt_val + 1'b1 );
                              end
                         end
                    end
                  else
                    begin 
                       if ( ( sis_decay == 1'b1 ) | ( sis_release == 1'b1 ) ) 
                         begin
                            if ( scnt_step_tc == 1'b1 ) 
                              begin
                                 if ( scnt_val > 0 ) 
                                   begin
                                      scnt_val <= ( scnt_val - 1'b1 );
                                   end
                              end
                         end
                    end
               end
          end
     end // always @ (  posedge clk)
   
   always @ (  sis_decay or  scnt_val or  s_level)
     begin
        if ( ( sis_decay == 1'b1 ) & ( scnt_val == s_level ) ) 
          begin
             sdecay_tc <= 1'b1;
          end
        else
          begin 
             sdecay_tc <= 1'b0;
          end
     end // always @ (  sis_decay or  scnt_val or  s_level)
   
   always @ (  sis_release or scnt_val )
     begin
        if ( ( sis_release == 1'b1 ) & ( scnt_val == 0 ) ) 
          begin
             srelease_tc <= 1'b1;
          end
        else
          begin 
             srelease_tc <= 1'b0;
          end
     end // always @ (  sis_release)
   
   always @ (  sis_decay or  sis_release or  scnt_val or  scnt_pwl or  s_level)
     begin
        if ( sis_decay == 1'b1 ) 
          begin
             //if ( scnt_val == ( $unsigned( ( 2 ** nbit_data ) - 1 ) - cval_thr_v[scnt_pwl] ) ) 
		  if ( scnt_val == ( $unsigned(cval_max) - cval_thr_v[scnt_pwl] ) )
               begin
                  scnt_val_tc <= 1'b1;
               end
             else
               begin 
                  scnt_val_tc <= 1'b0;
               end
          end
        else
          begin 
             if ( sis_release == 1'b1 ) 
               begin
                  if ( scnt_val == ( s_level - cval_thr_v[scnt_pwl] ) ) 
                    begin
                       scnt_val_tc <= 1'b1;
                    end
                  else
                    begin 
                       scnt_val_tc <= 1'b0;
                    end
               end
             else
               begin 
                  if ( scnt_val == cval_thr_v[scnt_pwl] ) 
                    begin
                       scnt_val_tc <= 1'b1;
                    end
                  else
                    begin 
                       scnt_val_tc <= 1'b0;
                    end
               end
          end
     end // always @ (  sis_decay or  sis_release or  scnt_val or  scnt_pwl or  s_level)
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             scnt_pwl <= 0;
          end
        else
          begin 
             if ( ( ( ( ( sis_idle == 1'b1 ) | ( sis_sustain == 1'b1 ) ) | ( sinit_cnt_from_attack == 1'b1 ) ) | ( sinit_cnt_from_decay == 1'b1 ) ) | ( sinit_cnt_from_release == 1'b1 ) ) 
               begin
                  scnt_pwl <= 0;
               end
             else
               begin 
                  if ( ( ( sis_attack == 1'b1 ) | ( sis_decay == 1'b1 ) ) | ( sis_release == 1'b1 ) ) 
                    begin
                       if ( ( scnt_val_tc == 1'b1 ) & ( scnt_step_tc == 1'b1 ) ) 
                         begin
                            //if ( scnt_pwl < $unsigned( 7 - 1 ) ) 
			    if ( scnt_pwl < $unsigned(cpwl_thr) ) 				    
                              begin
                                 scnt_pwl <= ( scnt_pwl + 1'b1 );
                              end
                            else
                              begin 
                                 scnt_pwl <= 0;
                              end
                         end
                    end
               end
          end
     end // always @ (  posedge clk)
   
   always @ (  scnt_pwl)
     begin
        //if ( scnt_pwl == $unsigned( 7 - 1 ) ) 
	if ( scnt_pwl == $unsigned(cpwl_thr) ) 	     		
          begin
             scnt_pwl_tc <= 1'b1;
          end
        else
          begin 
             scnt_pwl_tc <= 1'b0;
          end
     end // always @ (  scnt_pwl)
   
   assign sattack_tc = ( ( ( sis_attack & scnt_pwl_tc ) & scnt_val_tc ) & scnt_step_tc );
   assign dout = scnt_val;
   assign vout = ( ( ( sis_attack | sis_decay ) | sis_sustain ) | sis_release );
   
endmodule 


module wav_gen_simple_v(
			clk,
			rstn,
			per_adx_in,
			per_adx_valid_in,
			click_en_in,
			wsel,
			wout
			);
   //parameter [31:0]debug_mode  = 0;
   parameter [31:0]nbit_freq_adx  = 7;
   parameter [31:0]nbit_wav_in  = 6;
   parameter [31:0]nbit_wav_out  = 14;
   //parameter [31:0]nbit_bar  = 4;
   input clk;
   input rstn;
   input [( nbit_freq_adx - 1 ):0] per_adx_in;
   input 			   per_adx_valid_in;
   input 			   click_en_in;
   input [1:0] 			   wsel;
   output [( nbit_wav_out - 1 ):0] wout;
   
   //localparam nbit_frac_out  = ( nbit_wav_in + 1 );

   //localparam nbit_freq  = 16;

   localparam [nbit_wav_in-1:0] cwave_mx  = 6'b011111;
   localparam [nbit_wav_in-1:0] cwave_mn  = 6'b100001;
   
   wire [15:0] 			   sstep_cnt_thr_tri_squ_sin;
   wire [15:0] 			   sstep_cnt_thr_saw;
   wire [nbit_wav_in-1:0] 	   swave_squ_thr_up;
   wire [nbit_wav_in-1:0] 	   swave_squ_thr_down;
   wire [( nbit_wav_in - 1 ):0]    smem_rom_ampl_sin_val;
   reg [15:0] 			   sstep_cnt_thr;
   reg 				   snote_enable;
   reg 				   swave_enable;
   reg 				   sclick_enable;
   reg [15:0] 			   sstep_cnt;
   reg 				   sstep_cnt_tc;
   reg [( nbit_wav_in - 1 ):0] 	   swave_cnt_tri;

   reg 				   swave_cnt_tri_is_max;
   reg 				   swave_cnt_tri_is_squ_thr_up;
   reg 				   swave_cnt_tri_is_min;
   reg 				   swave_cnt_tri_is_squ_thr_down;
   reg 				   swave_cnt_neg;
   reg 				   swave_cnt_tri_down_up_n;
   reg 				   swave_squ_sel;
   reg [( nbit_wav_in - 1 ):0] 	   swave_tri;
   reg [( nbit_wav_in - 1 ):0] 	   swave_saw;
   reg [( nbit_wav_in - 1 ):0] 	   swave_squ;
   //reg [( nbit_wav_in - 1 ):0] 	   smem_rom_ampl_sin_adx;
   reg [( nbit_wav_in - 2 ):0] 	   smem_rom_ampl_sin_adx;	
   reg 				   smem_rom_ampl_sin_val_is_neg;
   reg [( nbit_wav_in - 1 ):0] 	   swave_sin;
   reg [( nbit_wav_in - 1 ):0] 	   swave;

   mem_rom_freq_tri_squ_sin rom_freq_tri_squ_sin_i (
						  .addr(per_adx_in),
						  .clk(clk),
						  .en(per_adx_valid_in),
						  .rstn(rstn),
						  .data_out(sstep_cnt_thr_tri_squ_sin)
						  );   

   mem_rom_freq_saw rom_freq_saw_i (
				  .addr(per_adx_in),
				  .clk(clk),
				  .en(per_adx_valid_in),
				  .rstn(rstn),
				  .data_out(sstep_cnt_thr_saw)
				  );   
   
   always @ (  wsel or  sstep_cnt_thr_saw or  sstep_cnt_thr_tri_squ_sin)
     begin
        if ( wsel == 2'b10 ) 
          begin
             sstep_cnt_thr <= sstep_cnt_thr_saw;
          end
        else
          begin 
             sstep_cnt_thr <= sstep_cnt_thr_tri_squ_sin;
          end
     end // always @ (  wsel or  sstep_cnt_thr_saw or  sstep_cnt_thr_tri_squ_sin)
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             snote_enable <= 1'b0;
             swave_enable <= 1'b0;
             sclick_enable <= 1'b0;
          end
        else
          begin 
             snote_enable <= per_adx_valid_in;
             swave_enable <= snote_enable;
             sclick_enable <= click_en_in;
          end
     end // always @ (  posedge clk or negedge rstn)
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             sstep_cnt <= 0;
          end
        else
          begin 
             if ( ( snote_enable == 1'b0 ) & ( sclick_enable == 1'b0 ) ) 
               begin
                  sstep_cnt <= 0;
               end
             else
               begin 
                  if ( sstep_cnt_tc == 1'b1 ) 
                    begin
                       sstep_cnt <= 0;
                    end
                  else
                    begin 
                       sstep_cnt <= ( sstep_cnt + 1'b1 );
                    end
               end
          end
     end // always @ (  posedge clk or negedge rstn)
   
   always @ ( sstep_cnt or sstep_cnt_thr )
     begin
        if ( $unsigned(sstep_cnt) >= $unsigned(( sstep_cnt_thr - 1'b1 )) ) 
          begin
             sstep_cnt_tc <= 1'b1;
          end
        else
          begin 
             sstep_cnt_tc <= 1'b0;
          end
     end // always @ ( sstep_cnt or sstep_cnt_thr )
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             swave_cnt_tri <= 0;	   
          end
        else
          begin 
             if ( ( sclick_enable == 1'b0 ) & ( snote_enable == 1'b0 ) ) 
               begin
                  swave_cnt_tri <= 0;
               end
             else
               begin 
                  if ( sstep_cnt_tc == 1'b1 ) 
                    begin
                       if ( swave_cnt_tri_down_up_n == 1'b0 ) 
                         begin
                            if ( swave_cnt_neg == 1'b1 ) 
                              begin
                                 swave_cnt_tri <= (  ~( swave_cnt_tri) + 1'b1 );
                              end
                            else
                              begin 
                                 swave_cnt_tri <= ( swave_cnt_tri + 1'b1 );
                              end
                         end
                       else
                         begin 
                            swave_cnt_tri <= ( swave_cnt_tri - 1'b1 );
                         end
                    end
               end

          end
     end // always @ (  posedge clk or negedge rstn)
   
   assign swave_squ_thr_up = cwave_mx - 1'b1;
   assign swave_squ_thr_down = cwave_mn + 1'b1;
   
   always @ (  swave_cnt_tri)
     begin
        if ( $signed(swave_cnt_tri) == $signed(cwave_mx) )
          begin
             swave_cnt_tri_is_max <= 1'b1;
          end
        else
          begin 
             swave_cnt_tri_is_max <= 1'b0;
          end
     end // always @ (  swave_cnt_tri)
   
   always @ (  swave_cnt_tri or  swave_squ_thr_up)
     begin
        if ( $signed(swave_cnt_tri) == $signed(swave_squ_thr_up) ) 
          begin
             swave_cnt_tri_is_squ_thr_up <= 1'b1;
          end
        else
          begin 
             swave_cnt_tri_is_squ_thr_up <= 1'b0;
          end
     end // always @ (  swave_cnt_tri or  swave_squ_thr_up)
   
   always @ (  swave_cnt_tri)
     begin
        if ( $signed(swave_cnt_tri) == $signed(cwave_mn) )
          begin
             swave_cnt_tri_is_min <= 1'b1;
          end
        else
          begin 
             swave_cnt_tri_is_min <= 1'b0;
          end
     end // always @ (  swave_cnt_tri)
   
   always @ (  swave_cnt_tri or  swave_squ_thr_down)
     begin
        if ( $signed(swave_cnt_tri) == $signed(swave_squ_thr_down) ) 
          begin
             swave_cnt_tri_is_squ_thr_down <= 1'b1;
          end
        else
          begin 
             swave_cnt_tri_is_squ_thr_down <= 1'b0;
          end
     end // always @ (  swave_cnt_tri or  swave_squ_thr_down)
   
   always @ (  wsel or  swave_cnt_tri_is_max)
     begin
        if ( wsel == 2'b10 ) 
          begin
             swave_cnt_neg <= swave_cnt_tri_is_max;
          end
        else
          begin 
             swave_cnt_neg <= 1'b0;
          end
     end // always @ (  wsel or  swave_cnt_tri_is_max)
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             swave_cnt_tri_down_up_n <= 1'b0;
          end
        else
          begin 
             if ( ( swave_cnt_tri_is_max == 1'b1 ) & ( swave_cnt_tri_is_min == 1'b0 ) ) 
               begin
                  if ( wsel == 2'b10 ) 
                    begin
                       swave_cnt_tri_down_up_n <= 1'b0;
                    end
                  else
                    begin 
                       swave_cnt_tri_down_up_n <= 1'b1;
                    end
               end
             else
               begin 
                  if ( ( swave_cnt_tri_is_max == 1'b0 ) & ( swave_cnt_tri_is_min == 1'b1 ) ) 
                    begin
                       swave_cnt_tri_down_up_n <= 1'b0;
                    end
               end
          end
     end // always @ (  posedge clk or negedge rstn)
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             swave_squ_sel <= 1'b0;
          end
        else
          begin 
             if ( ( ( sstep_cnt_tc == 1'b1 ) & ( swave_cnt_tri_down_up_n == 1'b0 ) ) & ( swave_cnt_tri_is_squ_thr_up == 1'b1 ) ) 
               begin
                  swave_squ_sel <= 1'b1;
               end
             else
               begin 
                  if ( ( ( sstep_cnt_tc == 1'b1 ) & ( swave_cnt_tri_down_up_n == 1'b1 ) ) & ( swave_cnt_tri_is_squ_thr_down == 1'b1 ) ) 
                    begin
                       swave_squ_sel <= 1'b0;
                    end
               end
          end
     end // always @ (  posedge clk or negedge rstn)
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             swave_tri <= 0;	   
             swave_saw <= 0;	   
             swave_squ <= 0;	   
          end
        else
          begin 
             if ( swave_enable == 1'b1 ) 
               begin
                  swave_tri <= swave_cnt_tri;
                  swave_saw <= swave_cnt_tri;
                  if ( swave_squ_sel == 1'b1 ) 
                    begin
                       swave_squ <= cwave_mx;		       
                    end
                  else
                    begin 
                       swave_squ <= cwave_mn;		       
                    end
               end
             else
               begin 
                  swave_tri <= 0;		   
                  swave_saw <= 0;		  
                  swave_squ <= 0;		   
               end
          end
     end // always @ (  posedge clk or negedge rstn)
   
   always @ (  swave_cnt_tri)
     begin
        if ( swave_cnt_tri[( nbit_wav_in - 1 )] == 1'b0 ) 
          begin
	     //smem_rom_ampl_sin_adx <= swave_cnt_tri;  
             smem_rom_ampl_sin_adx <= swave_cnt_tri[( nbit_wav_in - 2 ):0];
          end
        else
          begin 
             //smem_rom_ampl_sin_adx <= (  ~( swave_cnt_tri) + 1'b1 );
   	     smem_rom_ampl_sin_adx <= (  ~( swave_cnt_tri[( nbit_wav_in - 2 ):0]) + 1'b1 );
          end
     end // always @ (  swave_cnt_tri)
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             smem_rom_ampl_sin_val_is_neg <= 1'b0;
          end
        else
          begin 
             smem_rom_ampl_sin_val_is_neg <= swave_cnt_tri[( nbit_wav_in - 1 )];
          end
     end // always @ (  posedge clk or negedge rstn)
   
   mem_rom_ampl_sin rom_ampl_sin_i (
				  .addr(smem_rom_ampl_sin_adx),
				  .clk(clk),
				  .en(swave_enable),
				  .rstn(rstn),
				  .data_out(smem_rom_ampl_sin_val)
				  );   
   
   always @ (  smem_rom_ampl_sin_val_is_neg or  smem_rom_ampl_sin_val)
     begin
        if ( smem_rom_ampl_sin_val_is_neg == 1'b0 ) 
          begin
             swave_sin <= smem_rom_ampl_sin_val;
          end
        else
          begin 
             swave_sin <= (  ~( smem_rom_ampl_sin_val) + 1'b1 );
          end
     end // always @ (  smem_rom_ampl_sin_val_is_neg or  smem_rom_ampl_sin_val)
   
   always @ (  wsel or  swave_tri or  swave_squ or  swave_saw or  swave_sin)
     begin
        case ( wsel ) 
          2'b00:
            begin
               swave <= swave_tri;
            end
          2'b01:
            begin
               swave <= swave_squ;
            end
          2'b10:
            begin
               swave <= swave_saw;
            end
          2'b11:
            begin
               swave <= swave_sin;
            end
        endcase
     end // always @ (  wsel or  swave_tri or  swave_squ or  swave_saw or  swave_sin)
   
   assign wout = { swave, 2'b00 };
endmodule 


module mem_rom_ampl_sin (
			 rstn,
			 clk,
			 en,
			 addr,
			 data_out
			 );
// >>> Module Implementation Begin

// <<< Module Implementation End
endmodule

 


module mem_rom_freq_saw (
			 rstn,
			 clk,
			 en,
			 addr,
			 data_out
			 );
   
   input rstn;
   input clk;
   input en;
   input [6:0] addr;
   output reg [15:0] data_out;
   
   //localparam nbit_freq_adx_tri_squ_sin = 7;
   localparam nbit_freq_adx_saw = 7;   
   //localparam n_adx_tri_squ_sin = 2**nbit_freq_adx_tri_squ_sin;
   localparam n_adx_saw = 2**nbit_freq_adx_saw;
   //localparam n_val_sin = 32;   

   wire [15:0] 	     rom_freq_saw[0:n_adx_saw-1];

   assign rom_freq_saw[0] = 16'd0;
   assign rom_freq_saw[1] = 16'd0;
   assign rom_freq_saw[2] = 16'd0;
   assign rom_freq_saw[3] = 16'd0;
   assign rom_freq_saw[4] = 16'd0;
   assign rom_freq_saw[5] = 16'd0;
   assign rom_freq_saw[6] = 16'd0;
   assign rom_freq_saw[7] = 16'd0;
   assign rom_freq_saw[8] = 16'd0;
   assign rom_freq_saw[9] = 16'd0;
   assign rom_freq_saw[10] = 16'd0;
   assign rom_freq_saw[11] = 16'd0;
   assign rom_freq_saw[12] = 16'd48537;
   assign rom_freq_saw[13] = 16'd45812;
   assign rom_freq_saw[14] = 16'd43241;
   assign rom_freq_saw[15] = 16'd40814;
   assign rom_freq_saw[16] = 16'd38524;
   assign rom_freq_saw[17] = 16'd36361;
   assign rom_freq_saw[18] = 16'd34321;
   assign rom_freq_saw[19] = 16'd32394;
   assign rom_freq_saw[20] = 16'd30576;
   assign rom_freq_saw[21] = 16'd28860;
   assign rom_freq_saw[22] = 16'd27240;
   assign rom_freq_saw[23] = 16'd25711;
   assign rom_freq_saw[24] = 16'd24268;
   assign rom_freq_saw[25] = 16'd22906;
   assign rom_freq_saw[26] = 16'd21621;
   assign rom_freq_saw[27] = 16'd20407;
   assign rom_freq_saw[28] = 16'd19262;
   assign rom_freq_saw[29] = 16'd18181;
   assign rom_freq_saw[30] = 16'd17160;
   assign rom_freq_saw[31] = 16'd16197;
   assign rom_freq_saw[32] = 16'd15288;
   assign rom_freq_saw[33] = 16'd14430;
   assign rom_freq_saw[34] = 16'd13620;
   assign rom_freq_saw[35] = 16'd12856;
   assign rom_freq_saw[36] = 16'd12134;
   assign rom_freq_saw[37] = 16'd11453;
   assign rom_freq_saw[38] = 16'd10810;
   assign rom_freq_saw[39] = 16'd10204;
   assign rom_freq_saw[40] = 16'd9631;
   assign rom_freq_saw[41] = 16'd9090;
   assign rom_freq_saw[42] = 16'd8580;
   assign rom_freq_saw[43] = 16'd8099;
   assign rom_freq_saw[44] = 16'd7644;
   assign rom_freq_saw[45] = 16'd7215;
   assign rom_freq_saw[46] = 16'd6810;
   assign rom_freq_saw[47] = 16'd6428;
   assign rom_freq_saw[48] = 16'd6067;
   assign rom_freq_saw[49] = 16'd5727;
   assign rom_freq_saw[50] = 16'd5405;
   assign rom_freq_saw[51] = 16'd5102;
   assign rom_freq_saw[52] = 16'd4815;
   assign rom_freq_saw[53] = 16'd4545;
   assign rom_freq_saw[54] = 16'd4290;
   assign rom_freq_saw[55] = 16'd4049;
   assign rom_freq_saw[56] = 16'd3822;
   assign rom_freq_saw[57] = 16'd3608;
   assign rom_freq_saw[58] = 16'd3405;
   assign rom_freq_saw[59] = 16'd3214;
   assign rom_freq_saw[60] = 16'd3034;
   assign rom_freq_saw[61] = 16'd2863;
   assign rom_freq_saw[62] = 16'd2703;
   assign rom_freq_saw[63] = 16'd2551;
   assign rom_freq_saw[64] = 16'd2408;
   assign rom_freq_saw[65] = 16'd2273;
   assign rom_freq_saw[66] = 16'd2145;
   assign rom_freq_saw[67] = 16'd2025;
   assign rom_freq_saw[68] = 16'd1911;
   assign rom_freq_saw[69] = 16'd1804;
   assign rom_freq_saw[70] = 16'd1703;
   assign rom_freq_saw[71] = 16'd1607;
   assign rom_freq_saw[72] = 16'd1517;
   assign rom_freq_saw[73] = 16'd1432;
   assign rom_freq_saw[74] = 16'd1351;
   assign rom_freq_saw[75] = 16'd1275;
   assign rom_freq_saw[76] = 16'd1204;
   assign rom_freq_saw[77] = 16'd1136;
   assign rom_freq_saw[78] = 16'd1073;
   assign rom_freq_saw[79] = 16'd1012;
   assign rom_freq_saw[80] = 16'd956;
   assign rom_freq_saw[81] = 16'd902;
   assign rom_freq_saw[82] = 16'd851;
   assign rom_freq_saw[83] = 16'd803;
   assign rom_freq_saw[84] = 16'd758;
   assign rom_freq_saw[85] = 16'd716;
   assign rom_freq_saw[86] = 16'd676;
   assign rom_freq_saw[87] = 16'd638;
   assign rom_freq_saw[88] = 16'd602;
   assign rom_freq_saw[89] = 16'd568;
   assign rom_freq_saw[90] = 16'd536;
   assign rom_freq_saw[91] = 16'd506;
   assign rom_freq_saw[92] = 16'd478;
   assign rom_freq_saw[93] = 16'd451;
   assign rom_freq_saw[94] = 16'd426;
   assign rom_freq_saw[95] = 16'd402;
   assign rom_freq_saw[96] = 16'd379;
   assign rom_freq_saw[97] = 16'd358;
   assign rom_freq_saw[98] = 16'd338;
   assign rom_freq_saw[99] = 16'd319;
   assign rom_freq_saw[100] = 16'd301;
   assign rom_freq_saw[101] = 16'd284;
   assign rom_freq_saw[102] = 16'd268;
   assign rom_freq_saw[103] = 16'd253;
   assign rom_freq_saw[104] = 16'd239;
   assign rom_freq_saw[105] = 16'd225;
   assign rom_freq_saw[106] = 16'd213;
   assign rom_freq_saw[107] = 16'd201;
   assign rom_freq_saw[108] = 16'd190;
   assign rom_freq_saw[109] = 16'd179;
   assign rom_freq_saw[110] = 16'd169;
   assign rom_freq_saw[111] = 16'd159;
   assign rom_freq_saw[112] = 16'd150;
   assign rom_freq_saw[113] = 16'd142;
   assign rom_freq_saw[114] = 16'd134;
   assign rom_freq_saw[115] = 16'd127;
   assign rom_freq_saw[116] = 16'd119;
   assign rom_freq_saw[117] = 16'd113;
   assign rom_freq_saw[118] = 16'd106;
   assign rom_freq_saw[119] = 16'd100;
   assign rom_freq_saw[120] = 16'd0;
   assign rom_freq_saw[121] = 16'd0;
   assign rom_freq_saw[122] = 16'd0;
   assign rom_freq_saw[123] = 16'd0;
   assign rom_freq_saw[124] = 16'd0;
   assign rom_freq_saw[125] = 16'd0;
   assign rom_freq_saw[126] = 16'd0;
   assign rom_freq_saw[127] = 16'd0;
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             data_out <= 1804;			     
          end
        else
          begin 
             if ( en == 1'b1 ) 
               begin
                  data_out <= rom_freq_saw[addr];				  
               end
          end
     end
   
endmodule 


module mem_rom_freq_tri_squ_sin (
				 rstn,
				 clk,
				 en,
				 addr,
				 data_out
				 );
   
   input rstn;
   input clk;
   input en;
   input [6:0] addr;
   output reg [15:0] data_out;
   
   localparam nbit_freq_adx_tri_squ_sin = 7;
   //localparam nbit_freq_adx_saw = 7;   
   localparam n_adx_tri_squ_sin = 2**nbit_freq_adx_tri_squ_sin;
   //localparam n_adx_saw = 2**nbit_freq_adx_saw;
   //localparam n_val_sin = 32;   

   wire [15:0] 	     rom_freq_tri_squ_sin[0:n_adx_tri_squ_sin-1];

   assign rom_freq_tri_squ_sin[0] = 16'd0;
   assign rom_freq_tri_squ_sin[1] = 16'd0;
   assign rom_freq_tri_squ_sin[2] = 16'd0;
   assign rom_freq_tri_squ_sin[3] = 16'd0;
   assign rom_freq_tri_squ_sin[4] = 16'd0;
   assign rom_freq_tri_squ_sin[5] = 16'd0;
   assign rom_freq_tri_squ_sin[6] = 16'd0;
   assign rom_freq_tri_squ_sin[7] = 16'd0;
   assign rom_freq_tri_squ_sin[8] = 16'd0;
   assign rom_freq_tri_squ_sin[9] = 16'd0;
   assign rom_freq_tri_squ_sin[10] = 16'd0;
   assign rom_freq_tri_squ_sin[11] = 16'd0;
   assign rom_freq_tri_squ_sin[12] = 16'd24660;
   assign rom_freq_tri_squ_sin[13] = 16'd23276;
   assign rom_freq_tri_squ_sin[14] = 16'd21969;
   assign rom_freq_tri_squ_sin[15] = 16'd20736;
   assign rom_freq_tri_squ_sin[16] = 16'd19572;
   assign rom_freq_tri_squ_sin[17] = 16'd18474;
   assign rom_freq_tri_squ_sin[18] = 16'd17437;
   assign rom_freq_tri_squ_sin[19] = 16'd16458;
   assign rom_freq_tri_squ_sin[20] = 16'd15535;
   assign rom_freq_tri_squ_sin[21] = 16'd14663;
   assign rom_freq_tri_squ_sin[22] = 16'd13840;
   assign rom_freq_tri_squ_sin[23] = 16'd13063;
   assign rom_freq_tri_squ_sin[24] = 16'd12330;
   assign rom_freq_tri_squ_sin[25] = 16'd11638;
   assign rom_freq_tri_squ_sin[26] = 16'd10985;
   assign rom_freq_tri_squ_sin[27] = 16'd10368;
   assign rom_freq_tri_squ_sin[28] = 16'd9786;
   assign rom_freq_tri_squ_sin[29] = 16'd9237;
   assign rom_freq_tri_squ_sin[30] = 16'd8719;
   assign rom_freq_tri_squ_sin[31] = 16'd8229;
   assign rom_freq_tri_squ_sin[32] = 16'd7767;
   assign rom_freq_tri_squ_sin[33] = 16'd7331;
   assign rom_freq_tri_squ_sin[34] = 16'd6920;
   assign rom_freq_tri_squ_sin[35] = 16'd6532;
   assign rom_freq_tri_squ_sin[36] = 16'd6165;
   assign rom_freq_tri_squ_sin[37] = 16'd5819;
   assign rom_freq_tri_squ_sin[38] = 16'd5492;
   assign rom_freq_tri_squ_sin[39] = 16'd5184;
   assign rom_freq_tri_squ_sin[40] = 16'd4893;
   assign rom_freq_tri_squ_sin[41] = 16'd4618;
   assign rom_freq_tri_squ_sin[42] = 16'd4359;
   assign rom_freq_tri_squ_sin[43] = 16'd4115;
   assign rom_freq_tri_squ_sin[44] = 16'd3884;
   assign rom_freq_tri_squ_sin[45] = 16'd3666;
   assign rom_freq_tri_squ_sin[46] = 16'd3460;
   assign rom_freq_tri_squ_sin[47] = 16'd3266;
   assign rom_freq_tri_squ_sin[48] = 16'd3082;
   assign rom_freq_tri_squ_sin[49] = 16'd2909;
   assign rom_freq_tri_squ_sin[50] = 16'd2746;
   assign rom_freq_tri_squ_sin[51] = 16'd2592;
   assign rom_freq_tri_squ_sin[52] = 16'd2447;
   assign rom_freq_tri_squ_sin[53] = 16'd2309;
   assign rom_freq_tri_squ_sin[54] = 16'd2180;
   assign rom_freq_tri_squ_sin[55] = 16'd2057;
   assign rom_freq_tri_squ_sin[56] = 16'd1942;
   assign rom_freq_tri_squ_sin[57] = 16'd1833;
   assign rom_freq_tri_squ_sin[58] = 16'd1730;
   assign rom_freq_tri_squ_sin[59] = 16'd1633;
   assign rom_freq_tri_squ_sin[60] = 16'd1541;
   assign rom_freq_tri_squ_sin[61] = 16'd1455;
   assign rom_freq_tri_squ_sin[62] = 16'd1373;
   assign rom_freq_tri_squ_sin[63] = 16'd1296;
   assign rom_freq_tri_squ_sin[64] = 16'd1223;
   assign rom_freq_tri_squ_sin[65] = 16'd1155;
   assign rom_freq_tri_squ_sin[66] = 16'd1090;
   assign rom_freq_tri_squ_sin[67] = 16'd1029;
   assign rom_freq_tri_squ_sin[68] = 16'd971;
   assign rom_freq_tri_squ_sin[69] = 16'd916;
   assign rom_freq_tri_squ_sin[70] = 16'd865;
   assign rom_freq_tri_squ_sin[71] = 16'd816;
   assign rom_freq_tri_squ_sin[72] = 16'd771;
   assign rom_freq_tri_squ_sin[73] = 16'd727;
   assign rom_freq_tri_squ_sin[74] = 16'd687;
   assign rom_freq_tri_squ_sin[75] = 16'd648;
   assign rom_freq_tri_squ_sin[76] = 16'd612;
   assign rom_freq_tri_squ_sin[77] = 16'd577;
   assign rom_freq_tri_squ_sin[78] = 16'd545;
   assign rom_freq_tri_squ_sin[79] = 16'd514;
   assign rom_freq_tri_squ_sin[80] = 16'd485;
   assign rom_freq_tri_squ_sin[81] = 16'd458;
   assign rom_freq_tri_squ_sin[82] = 16'd432;
   assign rom_freq_tri_squ_sin[83] = 16'd408;
   assign rom_freq_tri_squ_sin[84] = 16'd385;
   assign rom_freq_tri_squ_sin[85] = 16'd364;
   assign rom_freq_tri_squ_sin[86] = 16'd343;
   assign rom_freq_tri_squ_sin[87] = 16'd324;
   assign rom_freq_tri_squ_sin[88] = 16'd306;
   assign rom_freq_tri_squ_sin[89] = 16'd289;
   assign rom_freq_tri_squ_sin[90] = 16'd272;
   assign rom_freq_tri_squ_sin[91] = 16'd257;
   assign rom_freq_tri_squ_sin[92] = 16'd243;
   assign rom_freq_tri_squ_sin[93] = 16'd229;
   assign rom_freq_tri_squ_sin[94] = 16'd216;
   assign rom_freq_tri_squ_sin[95] = 16'd204;
   assign rom_freq_tri_squ_sin[96] = 16'd193;
   assign rom_freq_tri_squ_sin[97] = 16'd182;
   assign rom_freq_tri_squ_sin[98] = 16'd172;
   assign rom_freq_tri_squ_sin[99] = 16'd162;
   assign rom_freq_tri_squ_sin[100] = 16'd153;
   assign rom_freq_tri_squ_sin[101] = 16'd144;
   assign rom_freq_tri_squ_sin[102] = 16'd136;
   assign rom_freq_tri_squ_sin[103] = 16'd129;
   assign rom_freq_tri_squ_sin[104] = 16'd121;
   assign rom_freq_tri_squ_sin[105] = 16'd115;
   assign rom_freq_tri_squ_sin[106] = 16'd108;
   assign rom_freq_tri_squ_sin[107] = 16'd102;
   assign rom_freq_tri_squ_sin[108] = 16'd96;
   assign rom_freq_tri_squ_sin[109] = 16'd91;
   assign rom_freq_tri_squ_sin[110] = 16'd86;
   assign rom_freq_tri_squ_sin[111] = 16'd81;
   assign rom_freq_tri_squ_sin[112] = 16'd76;
   assign rom_freq_tri_squ_sin[113] = 16'd72;
   assign rom_freq_tri_squ_sin[114] = 16'd68;
   assign rom_freq_tri_squ_sin[115] = 16'd64;
   assign rom_freq_tri_squ_sin[116] = 16'd61;
   assign rom_freq_tri_squ_sin[117] = 16'd57;
   assign rom_freq_tri_squ_sin[118] = 16'd54;
   assign rom_freq_tri_squ_sin[119] = 16'd51;
   assign rom_freq_tri_squ_sin[120] = 16'd0;
   assign rom_freq_tri_squ_sin[121] = 16'd0;
   assign rom_freq_tri_squ_sin[122] = 16'd0;
   assign rom_freq_tri_squ_sin[123] = 16'd0;
   assign rom_freq_tri_squ_sin[124] = 16'd0;
   assign rom_freq_tri_squ_sin[125] = 16'd0;
   assign rom_freq_tri_squ_sin[126] = 16'd0;
   assign rom_freq_tri_squ_sin[127] = 16'd0;
   
   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             data_out <= 16'd916;			     
          end
        else
          begin 
             if ( en == 1'b1 ) 
               begin
                  data_out <= rom_freq_tri_squ_sin[addr];				  
               end
          end
     end
   
endmodule 


Reference solution:
rtl/generated.v:    
   input rstn;
   input clk;
   input en;
   //input [5:0] addr;
   input [4:0] addr;	
   output reg [5:0] data_out;
   
   //localparam nbit_freq_adx_tri_squ_sin = 7;
   //localparam nbit_freq_adx_saw = 7;   
   //localparam n_adx_tri_squ_sin = 2**nbit_freq_adx_tri_squ_sin;
   //localparam n_adx_saw = 2**nbit_freq_adx_saw;
   localparam n_val_sin = 32;   

   wire [5:0] 	    rom_ampl_sin[0:n_val_sin-1];

   assign rom_ampl_sin[0] = 6'd0;
   assign rom_ampl_sin[1] = 6'd2;
   assign rom_ampl_sin[2] = 6'd3;
   assign rom_ampl_sin[3] = 6'd5;
   assign rom_ampl_sin[4] = 6'd6;
   assign rom_ampl_sin[5] = 6'd8;
   assign rom_ampl_sin[6] = 6'd9;
   assign rom_ampl_sin[7] = 6'd11;
   assign rom_ampl_sin[8] = 6'd12;
   assign rom_ampl_sin[9] = 6'd14;
   assign rom_ampl_sin[10] = 6'd15;
   assign rom_ampl_sin[11] = 6'd16;
   assign rom_ampl_sin[12] = 6'd18;
   assign rom_ampl_sin[13] = 6'd19;
   assign rom_ampl_sin[14] = 6'd20;
   assign rom_ampl_sin[15] = 6'd21;
   assign rom_ampl_sin[16] = 6'd22;
   assign rom_ampl_sin[17] = 6'd24;
   assign rom_ampl_sin[18] = 6'd25;
   assign rom_ampl_sin[19] = 6'd25;
   assign rom_ampl_sin[20] = 6'd26;
   assign rom_ampl_sin[21] = 6'd27;
   assign rom_ampl_sin[22] = 6'd28;
   assign rom_ampl_sin[23] = 6'd28;
   assign rom_ampl_sin[24] = 6'd29;
   assign rom_ampl_sin[25] = 6'd30;
   assign rom_ampl_sin[26] = 6'd30;
   assign rom_ampl_sin[27] = 6'd30;
   assign rom_ampl_sin[28] = 6'd31;
   assign rom_ampl_sin[29] = 6'd31;
   assign rom_ampl_sin[30] = 6'd31;
   assign rom_ampl_sin[31] = 6'd31;  
   

   always @ (  posedge clk or negedge rstn)
     begin
        if ( rstn == 1'b0 ) 
          begin
             data_out <= 0;
          end
        else
          begin 
             if ( en == 1'b1 ) 
               begin
		  //data_out <= rom_ampl_sin[addr[4:0]];			  
		  data_out <= rom_ampl_sin[addr];			  
               end
             else
               begin 
                  data_out <= 0;
               end
          end
     end