URL
https://opencores.org/ocsvn/fixed_point_arithmetic_parameterized/fixed_point_arithmetic_parameterized/trunk
Subversion Repositories fixed_point_arithmetic_parameterized
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/fixed_point_arithmetic_parameterized/trunk/src/qdiv.v
1,87 → 1,86
`timescale 1ns / 1ps |
////////////////////////////////////////////////////////////////////////////////// |
// Company: |
// Engineer: |
// |
// Create Date: 19:39:14 08/24/2011 |
// Design Name: |
// Module Name: divider |
// Project Name: |
// Target Devices: |
// Tool versions: |
// Description: |
// |
// Dependencies: |
// |
// Revision: |
// Revision 0.01 - File Created |
// Additional Comments: |
// |
////////////////////////////////////////////////////////////////////////////////// |
|
module qdiv( |
input [N-1:0] dividend, |
input [N-1:0] divisor, |
input start, |
input clk, |
output [N-1:0] quotient_out, |
output complete |
); |
|
//Parameterized values |
parameter Q = 15; |
parameter N = 32; |
|
`timescale 1ns / 1ps |
////////////////////////////////////////////////////////////////////////////////// |
// Company: |
// Engineer: |
// |
// Create Date: 19:39:14 08/24/2011 |
// Design Name: |
// Module Name: divider |
// Project Name: |
// Target Devices: |
// Tool versions: |
// Description: |
// |
// Dependencies: |
// |
// Revision: |
// Revision 0.01 - File Created |
// Additional Comments: |
// |
////////////////////////////////////////////////////////////////////////////////// |
|
module qdiv( |
input [N-1:0] dividend, |
input [N-1:0] divisor, |
input start, |
input clk, |
output [N-1:0] quotient_out, |
output complete |
); |
|
//Parameterized values |
parameter Q = 15; |
parameter N = 32; |
|
reg [N-1:0] quotient; |
reg [N-1:0] dividend_copy; |
reg [N-1:0] dividend_copy; |
reg [2*(N-1)-1:0] divider_copy; |
|
reg [5:0] bit; |
|
reg [5:0] bit; |
reg done; |
|
initial done = 1; |
|
assign quotient_out = quotient; |
|
initial done = 1; |
|
assign quotient_out = quotient; |
assign complete = done; |
|
|
always @( posedge clk ) |
begin |
if( done && start ) begin |
|
|
done <= 1'b0; |
bit <= N+Q-2; |
quotient <= 0; |
dividend_copy <= {1'b0,dividend[N-2:0]}; |
|
dividend_copy <= {1'b0,dividend[N-2:0]}; |
|
divider_copy[2*(N-1)-1] <= 0; |
divider_copy[2*(N-1)-2:N-2] <= divisor[N-2:0]; |
divider_copy[N-3:0] <= 0; |
|
//set sign bit |
divider_copy[2*(N-1)-2:N-2] <= divisor[N-2:0]; |
divider_copy[N-3:0] <= 0; |
|
//set sign bit |
if((dividend[N-1] == 1 && divisor[N-1] == 0) || (dividend[N-1] == 0 && divisor[N-1] == 1)) |
quotient[N-1] <= 1; |
else |
quotient[N-1] <= 1; |
else |
quotient[N-1] <= 0; |
end |
end |
else if(!done) begin |
|
//compare divisor/dividend |
if(dividend_copy >= divider_copy) begin |
//subtract |
dividend_copy <= dividend_copy - divider_copy; |
//set quotient |
quotient[bit] <= 1'b1; |
end |
|
//reduce divisor |
divider_copy <= divider_copy >> 1; |
|
//reduce bit counter |
bit <= bit - 1; |
|
//stop condition |
if(dividend_copy == 0) |
done <= 1'b1; |
end |
end |
endmodule |
//compare divisor/dividend |
if(dividend_copy >= divider_copy) begin |
//subtract |
dividend_copy <= dividend_copy - divider_copy; |
//set quotient |
quotient[bit] <= 1'b1; |
end |
|
//reduce divisor |
divider_copy <= divider_copy >> 1; |
|
//stop condition |
if(bit == 0) |
done <= 1'b1; |
|
//reduce bit counter |
bit <= bit - 1; |
end |
end |
endmodule |
/fixed_point_arithmetic_parameterized/trunk/testfixtures/qdiv_tf.v
1,65 → 1,173
`timescale 1ns / 1ps |
|
//////////////////////////////////////////////////////////////////////////////// |
// Company: |
// Engineer: |
// |
// Create Date: 19:41:28 08/24/2011 |
// Design Name: divider |
// Module Name: C:/Documents and Settings/samskalicky/Desktop/PLE/divider_tf.v |
// Project Name: PLE |
// Target Device: |
// Tool versions: |
// Description: |
// |
// Verilog Test Fixture created by ISE for module: divider |
// |
// Dependencies: |
// |
// Revision: |
// Revision 0.01 - File Created |
// Additional Comments: |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
`timescale 1ns / 1ps |
|
//////////////////////////////////////////////////////////////////////////////// |
// Company: |
// Engineer: |
// |
// Create Date: 19:41:28 08/24/2011 |
// Design Name: divider |
// Module Name: C:/Documents and Settings/samskalicky/Desktop/PLE/divider_tf.v |
// Project Name: PLE |
// Target Device: |
// Tool versions: |
// Description: |
// |
// Verilog Test Fixture created by ISE for module: divider |
// |
// Dependencies: |
// |
// Revision: |
// Revision 0.01 - File Created |
// Additional Comments: |
// |
//////////////////////////////////////////////////////////////////////////////// |
|
module qdiv_tf; |
|
// Inputs |
reg [31:0] dividend; |
reg [31:0] divisor; |
reg start; |
//Parameterized values |
parameter Q = 15; |
parameter N = 32; |
|
// Inputs |
reg [N-1:0] dividend; |
reg [N-1:0] divisor; |
reg start; |
reg clk; |
|
// Outputs |
wire [31:0] quotient; |
|
// Instantiate the Unit Under Test (UUT) |
//module Params Name Signals |
qdiv #(15,32) uut (dividend, divisor, start, clk, quotient); |
|
initial begin |
real top; |
real bottom; |
|
// Outputs |
wire [N-1:0] quotient; |
wire done; |
real result; |
|
|
// Instantiate the Unit Under Test (UUT) |
//module Params Name Signals |
qdiv #(Q,N) uut (dividend, divisor, start, clk, quotient,done); |
|
initial begin |
// Initialize Inputs |
dividend[31] = 0; |
dividend[30:15] = 64; |
dividend[14:0] = 4096;//1048576;//4096; |
top = -32.5; |
bottom = 2.25; |
|
divisor[31] = 0; |
divisor[30:15] = 2; |
divisor[14:0] = 0; |
start = 1; |
clk = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
conv_rational(top,dividend); |
conv_rational(bottom,divisor); |
|
start = 1; |
clk = 0; |
|
// Wait 100 ns for global reset to finish |
#100; |
|
// Add stimulus here |
start = 0; |
|
#366; |
conv_fixed(quotient,result); |
$display("%f / %f = %f",top,bottom,result); |
end |
|
always |
begin |
#5 clk = ~clk; |
end |
|
always |
begin |
#5 clk = ~clk; |
end |
|
endmodule |
|
|
/* |
* Task to convert from rational to fixed point |
*/ |
task conv_rational; |
input real num; |
output [N-1:0] fixed; |
|
integer i; |
real tmp; |
|
begin |
tmp = num; |
|
//set sign |
if(tmp < 0) begin |
//if its negative, set the sign bit and make the temporary number position by multiplying by -1 |
fixed[N-1] = 1; |
tmp = tmp * -1; |
end |
else begin |
//if its positive, the sign bit is zero |
fixed[N-1] = 0; |
end |
|
//check that the number isnt too large |
if(tmp > (1 << N-Q-1)) begin |
$display("Error!!! rational number %f is larger than %d whole bits can represent!",num,N-Q-1); |
end |
|
//set whole part |
for(i=0; i<N-Q-1; i=i+1) begin |
if(tmp >= (1 << N-Q-2-i)) begin |
//if its greater or equal, subtract out this power of 2 and put a one at this position |
fixed[N-2-i] = 1; |
tmp = tmp - (1 << N-Q-2-i); |
end |
else begin |
//if its less, put a zero at this position |
fixed[N-2-i] = 0; |
end |
end |
|
//set fractional part |
for(i=1; i<=Q; i=i+1) begin |
if(tmp >= 1.0/(1 << i)) begin |
//if its greater or equal, subtract out this power of 2 and put a one at this position |
fixed[Q-i] = 1; |
tmp = tmp - 1.0/(1 << i); |
end |
else begin |
//if its less, put a zero at this position |
fixed[Q-i] = 0; |
end |
end |
|
//check that the number isnt too small (loss of precision) |
if(tmp > 0) begin |
$display("Error!!! LOSS OF PRECISION converting rational number %f's fractional part using %d bits!",num,Q); |
end |
end |
endtask; |
|
/* |
* Task to convert from fixed point to rational |
*/ |
task conv_fixed; |
input [N-1:0] fixed; |
output real num; |
|
integer i; |
|
begin |
num = 0; |
|
//set whole part |
for(i=0; i<N-Q-1; i=i+1) begin |
if(fixed[N-2-i] == 1) begin |
//if theres a one at this position, add the power of 2 to the rational number |
num = num + (1 << N-Q-2-i); |
end |
end |
|
//set fractional part |
for(i=1; i<=Q; i=i+1) begin |
if(fixed[Q-i] == 1) begin |
//if theres a one at this position, add the power of 2 to the rational number |
num = num + 1.0/(1 << i); |
end |
end |
|
//set sign |
if(fixed[N-1] == 1) begin |
//if the sign bit is set, negate the rational number |
num = num * -1; |
end |
end |
endtask; |
|
endmodule |