URL
https://opencores.org/ocsvn/sqmusic/sqmusic/trunk
Subversion Repositories sqmusic
[/] [sqmusic/] [trunk/] [sqm/] [sq_pg.v] - Rev 20
Go to most recent revision | Compare with Previous | Blame | View Log
/* SQmusic (c) Jose Tejada Gomez, 9th May 2013 You can use this file following the GNU GENERAL PUBLIC LICENSE version 3 Read the details of the license in: http://www.gnu.org/licenses/gpl.txt Send comments to: jose.tejada@ieee.org */ `timescale 1ns/1ps module sq_slot( input clk, input reset_n, input [10:0] fnumber, input [2:0] block, input [3:0] multiple, input [6:0] totallvl, // total level output [13:0] linear ); reg [7:0]state; parameter st_pg_count = 8'h01; parameter st_pow_read = 8'h04; wire [9:0]phase; wire [13:0] sin_log, sin_linear; reg pg_ce_n, pow_rd_n; always @(posedge clk or negedge reset_n ) begin if (!reset_n) begin state <= 8'b0; pg_ce_n <= 1'b1; pow_rd_n<= 1'b1; end else begin if( state == 8'd143 ) state <= 8'd0; else state <= state+1; pg_ce_n <= state == st_pg_count ? 1'b0 : 1'b1; pow_rd_n<= state == st_pow_read ? 1'b0 : 1'b1; end end sq_pg pg( .clk (clk), .reset_n (reset_n), .fnumber (fnumber), .block (block), .multiple(multiple), .ce_n (pg_ce_n), .phase (phase) ); sq_sin sin( .clk (clk), .reset_n (reset_n), .phase (phase), .gain (totallvl), .val (sin_log) ); sq_pow pow( .clk (clk), .reset_n (reset_n), .rd_n (pow_rd_n), .x (sin_log), .y (linear) ); endmodule /////////////////////////////////////////////////////////////////// module sq_pg( input clk, input reset_n, input [10:0] fnumber, input [2:0] block, input [3:0] multiple, input ce_n, // count enable, active low output [9:0]phase ); reg [19:0] count; assign phase = count[19:10]; wire [19:0]fmult = fnumber << (block-1); always @(posedge clk or negedge reset_n ) begin if( !reset_n ) count <= 20'b0; else begin if( !ce_n ) count <= count + ( multiple==4'b0 ? fmult>> 1 : fmult*multiple); else count <= count; end end endmodule /////////////////////////////////////////////////////////////////// module sq_sin( input clk, input reset_n, input [6:0]gain, // gain factor in log scale input [9:0]phase, output [13:0] val // LSB is the sign. 0=positive, 1=negative ); reg [12:0] sin_table[1023:0]; initial begin $readmemh("../tables/sin_table.hex", sin_table); end reg [9:0]last_phase; assign val = sin_table[last_phase] + { gain, 6'h0 }; always @(posedge clk or negedge reset_n ) begin if( !reset_n ) last_phase <= 10'b0; else begin last_phase <= phase; end end endmodule /////////////////////////////////////////////////////////////////// // sq_pow => reverse the log2 conversion module sq_pow( input clk, input reset_n, input rd_n, // read enable, active low input [13:0]x, // LSB is the sign. 0=positive, 1=negative output reg [13:0]y ); parameter st_input = 3'b000; parameter st_lut_read = 3'b001; parameter st_shift = 3'b010; parameter st_sign = 3'b011; parameter st_output = 3'b100; reg [2:0] state; reg [12:0] pow_table[255:0]; initial begin $readmemh("../tables/pow_table.hex", pow_table); end reg [7:0]index; reg [4:0]exp; reg sign; reg [13:0] raw, shifted, final; always @(posedge clk or negedge reset_n ) begin if( !reset_n ) begin index <= 8'b0; exp <= 3'b0; sign <= 1'b0; raw <= 14'b0; shifted <= 14'b0; y <= 14'b0; state <= st_input; end else begin case ( state ) st_input: begin if( !rd_n ) begin exp <= x[13:9]; index <= x[8:1]; sign <= x[0]; state <= st_lut_read; end else state <= st_input; end st_lut_read: begin raw <= pow_table[index]; state <= st_shift; end st_shift: begin shifted <= raw >> exp; state <= st_sign; end st_sign: begin final <= sign ? ~shifted + 1'b1 : shifted; state <= st_output; end st_output: begin y <= final; state <= st_input; end default: begin state <= st_input; end endcase end end always @(posedge clk or negedge reset_n ) begin if( !reset_n ) raw <= 13'b0; else raw <= pow_table[index]; end always @(posedge clk or negedge reset_n ) begin if( !reset_n ) shifted <= 13'b0; else shifted <= raw >> exp; end endmodule
Go to most recent revision | Compare with Previous | Blame | View Log