aboutsummaryrefslogtreecommitdiffstats
path: root/sdr_lib/small_hb_dec.v
diff options
context:
space:
mode:
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>2008-09-08 01:00:12 +0000
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>2008-09-08 01:00:12 +0000
commit61f2f0214c5999ea42a368a4fc99f03d8eb28d1e (patch)
treee7e24a9adc05ff1422fe3ada9926a51634741b47 /sdr_lib/small_hb_dec.v
downloaduhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.tar.gz
uhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.tar.bz2
uhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.zip
Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top-level components. Trunk passes distcheck with mb-gcc installed, but currently not without them. The key issue is that when mb-gcc is not installed, the build system skips over the usrp2/firmware directory, and the firmware include files don't get put into the dist tarball. But we can't do the usual DIST_SUBDIRS method as the firmware is a subpackage.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9528 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'sdr_lib/small_hb_dec.v')
-rw-r--r--sdr_lib/small_hb_dec.v99
1 files changed, 99 insertions, 0 deletions
diff --git a/sdr_lib/small_hb_dec.v b/sdr_lib/small_hb_dec.v
new file mode 100644
index 000000000..9957de15a
--- /dev/null
+++ b/sdr_lib/small_hb_dec.v
@@ -0,0 +1,99 @@
+// 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)
+module small_hb_dec
+ #(parameter WIDTH=18)
+ (input clk,
+ input rst,
+ input bypass,
+ input stb_in,
+ input [WIDTH-1:0] data_in,
+ output reg stb_out,
+ output [WIDTH-1:0] data_out);
+
+ reg stb_in_d1;
+ reg [WIDTH-1:0] data_in_d1;
+ always @(posedge clk) stb_in_d1 <= stb_in;
+ always @(posedge clk) data_in_d1 <= data_in;
+
+ wire go;
+ reg phase, go_d1, go_d2, go_d3, go_d4;
+ always @(posedge clk)
+ if(rst)
+ phase <= 0;
+ else if(stb_in_d1)
+ phase <= ~phase;
+ assign go = stb_in_d1 & phase;
+ always @(posedge clk) go_d1 <= go;
+ always @(posedge clk) go_d2 <= go_d1;
+ always @(posedge clk) go_d3 <= go_d2;
+ always @(posedge clk) go_d4 <= go_d3;
+
+ wire [17:0] coeff_a = -10690;
+ wire [17:0] coeff_b = 75809;
+
+ reg [WIDTH-1:0] d1, d2, d3, d4 , d5, d6;
+ always @(posedge clk)
+ if(stb_in_d1 | rst)
+ begin
+ d1 <= data_in_d1;
+ d2 <= d1;
+ d3 <= d2;
+ d4 <= d3;
+ d5 <= d4;
+ d6 <= d5;
+ end
+
+ reg [17:0] sum_a, sum_b, middle, middle_d1;
+ wire [17:0] sum_a_unreg, sum_b_unreg;
+ add2 #(.WIDTH(18)) add2_a (.in1(data_in_d1),.in2(d6),.sum(sum_a_unreg));
+ add2 #(.WIDTH(18)) add2_b (.in1(d2),.in2(d4),.sum(sum_b_unreg));
+
+ always @(posedge clk)
+ if(go)
+ begin
+ sum_a <= sum_a_unreg;
+ sum_b <= sum_b_unreg;
+ middle <= d3;
+ end
+
+ always @(posedge clk)
+ if(go_d1)
+ middle_d1 <= middle;
+
+ wire [17:0] sum = go_d1 ? sum_b : sum_a;
+ wire [17:0] coeff = go_d1 ? coeff_b : coeff_a;
+ wire [35:0] prod;
+ MULT18X18S mult(.C(clk), .CE(go_d1 | go_d2), .R(rst), .P(prod), .A(coeff), .B(sum) );
+
+ reg [35:0] accum;
+ always @(posedge clk)
+ if(rst)
+ accum <= 0;
+ else if(go_d2)
+ accum <= {middle_d1[17],middle_d1[17],middle_d1,16'd0} + {prod};
+ else if(go_d3)
+ accum <= accum + {prod};
+
+ wire [17:0] accum_rnd;
+ round #(.bits_in(36),.bits_out(18)) round_acc (.in(accum),.out(accum_rnd));
+
+ reg [17:0] final_sum;
+ always @(posedge clk)
+ if(bypass)
+ final_sum <= data_in_d1;
+ else if(go_d4)
+ final_sum <= accum_rnd;
+
+ assign data_out = final_sum;
+
+ always @(posedge clk)
+ if(rst)
+ stb_out <= 0;
+ else if(bypass)
+ stb_out <= stb_in_d1;
+ else
+ stb_out <= go_d4;
+endmodule // small_hb_dec