[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r8864 - usrp2/trunk/fpga/sdr_lib
From: |
matt |
Subject: |
[Commit-gnuradio] r8864 - usrp2/trunk/fpga/sdr_lib |
Date: |
Thu, 10 Jul 2008 19:00:39 -0600 (MDT) |
Author: matt
Date: 2008-07-10 19:00:37 -0600 (Thu, 10 Jul 2008)
New Revision: 8864
Added:
usrp2/trunk/fpga/sdr_lib/hb_interp_tb.v
Modified:
usrp2/trunk/fpga/sdr_lib/dsp_core_tx.v
usrp2/trunk/fpga/sdr_lib/hb_interp.v
Log:
believed to be working hb_interp, plus changes to dsp_core_tx to tell it the
decimation rate
Modified: usrp2/trunk/fpga/sdr_lib/dsp_core_tx.v
===================================================================
--- usrp2/trunk/fpga/sdr_lib/dsp_core_tx.v 2008-07-11 00:33:32 UTC (rev
8863)
+++ usrp2/trunk/fpga/sdr_lib/dsp_core_tx.v 2008-07-11 01:00:37 UTC (rev
8864)
@@ -69,11 +69,15 @@
wire [17:0] i_interp, q_interp;
wire [17:0] hb1_i, hb1_q, hb2_i, hb2_q;
+
+ wire [7:0] cpo = enable_hb2 ? ({interp_rate,1'b0}) : interp_rate;
+ // Note that max CIC rate is 128, which would give an overflow on cpo if
enable_hb2 is true,
+ // but the default case inside hb_interp handles this
- hb_interp #(.WIDTH(18)) hb_interp_i
-
(.clk(clk),.rst(rst),.bypass(~enable_hb1),.stb_in(strobe_hb1),.data_in(bb_i),.stb_out(strobe_hb2),.data_out(hb1_i));
- hb_interp #(.WIDTH(18)) hb_interp_q
-
(.clk(clk),.rst(rst),.bypass(~enable_hb1),.stb_in(strobe_hb1),.data_in(bb_q),.stb_out(strobe_hb2),.data_out(hb1_q));
+ hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_i
+
(.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in(bb_i),.stb_out(strobe_hb2),.data_out(hb1_i));
+ hb_interp #(.IWIDTH(18),.OWIDTH(18),.ACCWIDTH(24)) hb_interp_q
+
(.clk(clk),.rst(rst),.bypass(~enable_hb1),.cpo(cpo),.stb_in(strobe_hb1),.data_in(bb_q),.stb_out(strobe_hb2),.data_out(hb1_q));
small_hb_int #(.WIDTH(18)) small_hb_interp_i
(.clk(clk),.rst(rst),.bypass(~enable_hb2),.stb_in(strobe_hb2),.data_in(hb1_i),
Modified: usrp2/trunk/fpga/sdr_lib/hb_interp.v
===================================================================
--- usrp2/trunk/fpga/sdr_lib/hb_interp.v 2008-07-11 00:33:32 UTC (rev
8863)
+++ usrp2/trunk/fpga/sdr_lib/hb_interp.v 2008-07-11 01:00:37 UTC (rev
8864)
@@ -1,22 +1,157 @@
-// Short halfband decimator (intended to be followed by another stage)
-// Implements impulse responses of the form [A 0 B 0.5 B 0 A]
-//
-// These taps designed by halfgen4 from ldoolittle:
-// 2 * 131072 * halfgen4(.75/8,2)
+// First halfband iterpolator
+// Implements impulse responses of the form [A 0 B 0 C .. 0 H 0.5 H 0 .. C 0 B
0 A]
+// Strobe in cannot come faster than every 4th clock cycle,
+// Strobe out cannot come faster than every 2nd clock cycle
+
+// These taps designed by halfgen4 from ldoolittle
+// myfilt = round(2^18 * halfgen4(.7/4,8))
+
module hb_interp
- #(parameter WIDTH=18)
+ #(parameter IWIDTH=18, OWIDTH=18, ACCWIDTH=24)
(input clk,
input rst,
input bypass,
+ input [7:0] cpo, // Clocks per output, must be at least 2
input stb_in,
- input [WIDTH-1:0] data_in,
+ input [IWIDTH-1:0] data_in,
input stb_out,
- output reg [WIDTH-1:0] data_out);
+ output reg [OWIDTH-1:0] data_out);
+ localparam MWIDTH = ACCWIDTH-2;
+ localparam CWIDTH = 18;
+
+ reg [CWIDTH-1:0] coeff1, coeff2;
+ reg [3:0] addr_a, addr_b, addr_c, addr_d, addr_e;
+ wire [IWIDTH-1:0] data_a, data_b, data_c, data_d, data_e, sum1, sum2;
+ wire [35:0] prod1, prod2;
+
+ reg [2:0] phase, phase_d1, phase_d2, phase_d3, phase_d4, phase_d5;
+
always @(posedge clk)
+ if(rst)
+ phase <= 0;
+ else
+ if(stb_in)
+ phase <= 1;
+ else if(phase==4)
+ phase <= 0;
+ else if(phase!=0)
+ phase <= phase + 1;
+ always @(posedge clk) phase_d1 <= phase;
+ always @(posedge clk) phase_d2 <= phase_d1;
+ always @(posedge clk) phase_d3 <= phase_d2;
+ always @(posedge clk) phase_d4 <= phase_d3;
+ always @(posedge clk) phase_d5 <= phase_d4;
+
+ srl #(.WIDTH(IWIDTH)) srl_a
+ (.clk(clk),.write(stb_in),.in(data_in),.addr(addr_a),.out(data_a));
+ srl #(.WIDTH(IWIDTH)) srl_b
+ (.clk(clk),.write(stb_in),.in(data_in),.addr(addr_b),.out(data_b));
+ srl #(.WIDTH(IWIDTH)) srl_c
+ (.clk(clk),.write(stb_in),.in(data_in),.addr(addr_c),.out(data_c));
+ srl #(.WIDTH(IWIDTH)) srl_d
+ (.clk(clk),.write(stb_in),.in(data_in),.addr(addr_d),.out(data_d));
+ srl #(.WIDTH(IWIDTH)) srl_e
+ (.clk(clk),.write(stb_in),.in(data_in),.addr(addr_e),.out(data_e));
+
+ always @*
+ case(phase)
+ 1 : begin addr_a = 0; addr_b = 15; end
+ 2 : begin addr_a = 1; addr_b = 14; end
+ 3 : begin addr_a = 2; addr_b = 13; end
+ 4 : begin addr_a = 3; addr_b = 12; end
+ default : begin addr_a = 0; addr_b = 15; end
+ endcase // case(phase)
+
+ always @*
+ case(phase)
+ 1 : begin addr_c = 4; addr_d = 11; end
+ 2 : begin addr_c = 5; addr_d = 10; end
+ 3 : begin addr_c = 6; addr_d = 9; end
+ 4 : begin addr_c = 7; addr_d = 8; end
+ default : begin addr_c = 4; addr_d = 11; end
+ endcase // case(phase)
+
+ always @*
+ case(cpo)
+ 2 : addr_e <= 9;
+ 3,4,5,6,7,8 : addr_e <= 8;
+ default : addr_e <= 7; // This case works for 256, which = 0 due to
overflow outside this block
+ endcase // case(cpo)
+
+ always @* // Outer coeffs
+ case(phase_d1)
+ 1 : coeff1 = -107;
+ 2 : coeff1 = 445;
+ 3 : coeff1 = -1271;
+ 4 : coeff1 = 2959;
+ default : coeff1 = -107;
+ endcase // case(phase)
+
+ always @* // Inner coeffs
+ case(phase_d1)
+ 1 : coeff2 = -6107;
+ 2 : coeff2 = 11953;
+ 3 : coeff2 = -24706;
+ 4 : coeff2 = 82359;
+ default : coeff2 = -6107;
+ endcase // case(phase)
+
+ add2_reg /*_and_round_reg*/ #(.WIDTH(IWIDTH)) add1
(.clk(clk),.in1(data_a),.in2(data_b),.sum(sum1));
+ add2_reg /*_and_round_reg*/ #(.WIDTH(IWIDTH)) add2
(.clk(clk),.in1(data_c),.in2(data_d),.sum(sum2));
+ // sum1, sum2 available on phase_d1
+
+ wire do_mult = 1;
+ MULT18X18S mult1(.C(clk), .CE(do_mult), .R(rst), .P(prod1), .A(coeff1),
.B(sum1) );
+ MULT18X18S mult2(.C(clk), .CE(do_mult), .R(rst), .P(prod2), .A(coeff2),
.B(sum2) );
+ // prod1, prod2 available on phase_d2
+
+ wire [MWIDTH-1:0] sum_of_prod;
+
+ add2_and_round_reg #(.WIDTH(MWIDTH))
+ add3
(.clk(clk),.in1(prod1[35:36-MWIDTH]),.in2(prod2[35:36-MWIDTH]),.sum(sum_of_prod));
+ // sum_of_prod available on phase_d3
+
+ wire [ACCWIDTH-1:0] acc_out;
+ wire [OWIDTH-1:0] acc_round;
+
+ wire clear = (phase_d3 == 1);
+ wire do_acc = (phase_d3 != 0);
+
+ acc #(.IWIDTH(MWIDTH),.OWIDTH(ACCWIDTH))
+ acc
(.clk(clk),.clear(clear),.acc(do_acc),.in(sum_of_prod),.out(acc_out));
+ // acc_out available on phase_d4
+
+ wire [ACCWIDTH-6:0] clipped_acc;
+ clip #(.bits_in(ACCWIDTH),.bits_out(ACCWIDTH-5))
final_clip(.in(acc_out),.out(clipped_acc));
+
+ reg [ACCWIDTH-6:0] clipped_reg;
+ always @(posedge clk)
+ if(phase_d4 == 4)
+ clipped_reg <= clipped_acc;
+ // clipped_reg available on phase_d5
+
+ wire [OWIDTH-1:0] data_out_round;
+ round #(.bits_in(ACCWIDTH-5),.bits_out(OWIDTH)) final_round
(.in(clipped_reg),.out(data_out_round));
+
+ reg odd;
+ always @(posedge clk)
+ if(rst)
+ odd <= 0;
+ else if(stb_in)
+ odd <= 0;
+ else if(stb_out)
+ odd <= 1;
+
+ always @(posedge clk)
if(bypass)
data_out <= data_in;
- else
- data_out <= 0;
+ else if(stb_out)
+ if(odd)
+ data_out <= data_e;
+ else
+ data_out <= data_out_round;
+ // data_out available on phase_d6
+
endmodule // hb_interp
Added: usrp2/trunk/fpga/sdr_lib/hb_interp_tb.v
===================================================================
--- usrp2/trunk/fpga/sdr_lib/hb_interp_tb.v (rev 0)
+++ usrp2/trunk/fpga/sdr_lib/hb_interp_tb.v 2008-07-11 01:00:37 UTC (rev
8864)
@@ -0,0 +1,132 @@
+module hb_interp_tb( ) ;
+
+ // Parameters for instantiation
+ parameter clocks = 8'd2 ; // Number of clocks per output
+ parameter decim = 1 ; // Sets the filter to decimate
+ parameter rate = 2 ; // Sets the decimation rate
+
+ reg clock ;
+ reg reset ;
+ reg enable ;
+ wire strobe_in ;
+ reg signed [17:0] data_in ;
+ wire strobe_out ;
+ wire signed [17:0] data_out ;
+
+ initial
+ begin
+ $dumpfile("hb_interp_tb.vcd");
+ $dumpvars(0,hb_interp_tb);
+ end
+
+ // Setup the clock
+ initial clock = 1'b0 ;
+ always #5 clock <= ~clock ;
+
+ // Come out of reset after a while
+ initial reset = 1'b1 ;
+ initial #1000 reset = 1'b0 ;
+
+ always @(posedge clock)
+ enable <= ~reset;
+
+ // Instantiate UUT
+ /*
+ halfband_ideal
+ #(
+ .decim ( decim ),
+ .rate ( rate )
+ ) uut(
+ .clock ( clock ),
+ .reset ( reset ),
+ .enable ( enable ),
+ .strobe_in ( strobe_in ),
+ .data_in ( data_in ),
+ .strobe_out ( strobe_out ),
+ .data_out ( data_out )
+ ) ;
+ */
+
+ cic_strober #(.WIDTH(8))
+ out_strober(.clock(clock),.reset(reset),.enable(enable),.rate(clocks),
+ .strobe_fast(1),.strobe_slow(strobe_out) );
+
+ cic_strober #(.WIDTH(8))
+ in_strober(.clock(clock),.reset(reset),.enable(enable),.rate(2),
+ .strobe_fast(strobe_out),.strobe_slow(strobe_in) );
+
+ hb_interp #() uut
+
(.clk(clock),.rst(reset),.bypass(0),.cpo(clocks),.stb_in(strobe_in),.data_in(data_in),
+ .stb_out(strobe_out),/* .output_rate(clocks), */ .data_out(data_out) );
+
+ integer i, ri, ro, infile, outfile ;
+
+ always @(posedge clock)
+ begin
+ if(strobe_out)
+ $display(data_out);
+ end
+
+ // Setup file IO
+ initial begin
+ infile = $fopen("input.dat","r") ;
+ outfile = $fopen("output.dat","r") ;
+ $timeformat(-9, 2, " ns", 10) ;
+ end
+
+ reg endofsim ;
+ reg signed [17:0] compare ;
+ integer noe ;
+ initial noe = 0 ;
+
+ initial begin
+ // Initialize inputs
+ data_in <= 18'd0 ;
+
+ // Wait for reset to go away
+ @(negedge reset) #0 ;
+
+ // While we're still simulating ...
+ while( !endofsim ) begin
+
+ // Write the input from the file or 0 if EOF...
+ @( negedge clock ) begin
+ if(strobe_in)
+ if( !$feof(infile) )
+ ri <= #1 $fscanf( infile, "%d", data_in ) ;
+ else
+ data_in <= 18'd0 ;
+ end
+ end
+
+ // Print out the number of errors that occured
+ if( noe )
+ $display( "FAILED: %d errors during simulation", noe ) ;
+ else
+ $display( "PASSED: Simulation successful" ) ;
+
+ $finish ;
+ end
+
+ // Output comparison of simulated values versus known good values
+ always @ (posedge clock) begin
+ if( reset )
+ endofsim <= 1'b0 ;
+ else begin
+ if( !$feof(outfile) ) begin
+ if( strobe_out ) begin
+ ro = $fscanf( outfile, "%d\n", compare ) ;
+ if( compare != data_out ) begin
+ //$display( "%t: %d != %d", $realtime, data_out, compare ) ;
+ noe = noe + 1 ;
+ end
+ end
+ end else begin
+ // Signal end of simulation when no more outputs
+ if($feof(infile))
+ endofsim <= 1'b1 ;
+ end
+ end
+ end
+
+endmodule // small_hb_int_tb
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r8864 - usrp2/trunk/fpga/sdr_lib,
matt <=