OpenCores
URL https://opencores.org/ocsvn/sqmusic/sqmusic/trunk

Subversion Repositories sqmusic

[/] [sqmusic/] [trunk/] [sqm/] [sq_pg.v] - Rev 19

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,
  output [12:0] linear
);
 
wire [9:0]phase;
wire [12:0] sin_log, sin_linear;
 
sq_pg pg( 
  .clk     (clk), 
  .reset_n (reset_n), 
  .fnumber (fnumber), 
  .block   (block),
  .multiple(multiple),
  .phase   (phase) );
 
sq_sin sin(
  .clk     (clk), 
  .reset_n (reset_n), 
  .phase   (phase),
  .val     (sin_log) );
 
sq_pow pow(
  .clk     (clk), 
  .reset_n (reset_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,
	output [9:0]phase );
 
reg [19:0] count;
assign phase = count[19:10];
 
wire [19:0]fmult = fnumber << block;
 
always @(posedge clk or negedge reset_n ) begin
	if( !reset_n )
		count <= 20'b0;
	else begin
	  count <= count + ( multiple==4'b0 ? fmult>> 1 : fmult*multiple);
	end
end
 
endmodule
 
///////////////////////////////////////////////////////////////////
module sq_sin(
  input clk,
  input reset_n,
  input [9:0]phase,
  output [12: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];
 
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 [12:0]x, // LSB is the sign. 0=positive, 1=negative
  output reg [12: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 [3:0]exp;
reg sign;
 
reg [12: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   <= 13'b0;
		shifted <= 13'b0;
		y     <= 12'b0;
		state <= st_input;
	end
	else begin
	  case ( state )
	    st_input: begin
	      if( !rd_n ) begin
	        exp   <= x[12:9];
	        index <= x[8:1];
	        sign  <= x[0];
	        state <= st_lut_read;
	      end
	      else state <= st_lut_read;
	      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
	  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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.