root / usrp2 / sdr_lib / dsp_core_rx.v @ 7c057ae2
History | View | Annotate | Download (5.9 kB)
| 1 |
|
|---|---|
| 2 |
module dsp_core_rx |
| 3 |
#(parameter BASE = 160) |
| 4 |
(input clk, input rst, |
| 5 |
input set_stb, input [7:0] set_addr, input [31:0] set_data, |
| 6 |
|
| 7 |
input [13:0] adc_a, input adc_ovf_a, |
| 8 |
input [13:0] adc_b, input adc_ovf_b, |
| 9 |
|
| 10 |
input [15:0] io_rx, |
| 11 |
|
| 12 |
output [31:0] sample, |
| 13 |
input run, |
| 14 |
output strobe, |
| 15 |
output [31:0] debug |
| 16 |
); |
| 17 |
|
| 18 |
wire [15:0] scale_i, scale_q; |
| 19 |
wire [13:0] adc_a_ofs, adc_b_ofs; |
| 20 |
reg [13:0] adc_i, adc_q; |
| 21 |
wire [31:0] phase_inc; |
| 22 |
reg [31:0] phase; |
| 23 |
|
| 24 |
wire [35:0] prod_i, prod_q; |
| 25 |
wire [23:0] i_cordic, q_cordic; |
| 26 |
wire [23:0] i_cic, q_cic; |
| 27 |
wire [17:0] i_cic_scaled, q_cic_scaled; |
| 28 |
wire [17:0] i_hb1, q_hb1; |
| 29 |
wire [17:0] i_hb2, q_hb2; |
| 30 |
wire [15:0] i_out, q_out; |
| 31 |
|
| 32 |
wire strobe_cic, strobe_hb1, strobe_hb2; |
| 33 |
wire enable_hb1, enable_hb2; |
| 34 |
wire [7:0] cic_decim_rate; |
| 35 |
|
| 36 |
wire [31:10] UNUSED_1; |
| 37 |
wire [31:4] UNUSED_2; |
| 38 |
wire [31:2] UNUSED_3; |
| 39 |
|
| 40 |
setting_reg #(.my_addr(BASE+0)) sr_0 |
| 41 |
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), |
| 42 |
.in(set_data),.out(phase_inc),.changed()); |
| 43 |
|
| 44 |
setting_reg #(.my_addr(BASE+1)) sr_1 |
| 45 |
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), |
| 46 |
.in(set_data),.out({scale_i,scale_q}),.changed());
|
| 47 |
|
| 48 |
setting_reg #(.my_addr(BASE+2)) sr_2 |
| 49 |
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), |
| 50 |
.in(set_data),.out({UNUSED_1, enable_hb1, enable_hb2, cic_decim_rate}),.changed());
|
| 51 |
|
| 52 |
rx_dcoffset #(.WIDTH(14),.ADDR(BASE+3)) rx_dcoffset_a |
| 53 |
(.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), |
| 54 |
.adc_in(adc_a),.adc_out(adc_a_ofs)); |
| 55 |
|
| 56 |
rx_dcoffset #(.WIDTH(14),.ADDR(BASE+4)) rx_dcoffset_b |
| 57 |
(.clk(clk),.rst(rst),.set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), |
| 58 |
.adc_in(adc_b),.adc_out(adc_b_ofs)); |
| 59 |
|
| 60 |
wire [7:0] muxctrl; |
| 61 |
setting_reg #(.my_addr(BASE+5), .width(8)) sr_8 |
| 62 |
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), |
| 63 |
.in(set_data),.out({UNUSED_2,muxctrl}),.changed());
|
| 64 |
|
| 65 |
wire [1:0] gpio_ena; |
| 66 |
setting_reg #(.my_addr(BASE+6), .width(2)) sr_9 |
| 67 |
(.clk(clk),.rst(rst),.strobe(set_stb),.addr(set_addr), |
| 68 |
.in(set_data),.out({UNUSED_3,gpio_ena}),.changed());
|
| 69 |
|
| 70 |
always @(posedge clk) |
| 71 |
case(muxctrl[3:0]) // The I mapping |
| 72 |
0: adc_i <= adc_a_ofs; |
| 73 |
1: adc_i <= adc_b_ofs; |
| 74 |
2: adc_i <= 0; |
| 75 |
default: adc_i <= 0; |
| 76 |
endcase // case (muxctrl[3:0]) |
| 77 |
|
| 78 |
always @(posedge clk) |
| 79 |
case(muxctrl[7:4]) // The Q mapping |
| 80 |
0: adc_q <= adc_a_ofs; |
| 81 |
1: adc_q <= adc_b_ofs; |
| 82 |
2: adc_q <= 0; |
| 83 |
default: adc_q <= 0; |
| 84 |
endcase // case (muxctrl[7:4]) |
| 85 |
|
| 86 |
always @(posedge clk) |
| 87 |
if(rst) |
| 88 |
phase <= 0; |
| 89 |
else if(~run) |
| 90 |
phase <= 0; |
| 91 |
else |
| 92 |
phase <= phase + phase_inc; |
| 93 |
|
| 94 |
MULT18X18S mult_i |
| 95 |
(.P(prod_i), // 36-bit multiplier output |
| 96 |
.A({{4{adc_i[13]}},adc_i} ), // 18-bit multiplier input
|
| 97 |
.B({{2{scale_i[15]}},scale_i}), // 18-bit multiplier input
|
| 98 |
.C(clk), // Clock input |
| 99 |
.CE(1), // Clock enable input |
| 100 |
.R(rst) // Synchronous reset input |
| 101 |
); |
| 102 |
|
| 103 |
MULT18X18S mult_q |
| 104 |
(.P(prod_q), // 36-bit multiplier output |
| 105 |
.A({{4{adc_q[13]}},adc_q} ), // 18-bit multiplier input
|
| 106 |
.B({{2{scale_q[15]}},scale_q}), // 18-bit multiplier input
|
| 107 |
.C(clk), // Clock input |
| 108 |
.CE(1), // Clock enable input |
| 109 |
.R(rst) // Synchronous reset input |
| 110 |
); |
| 111 |
|
| 112 |
|
| 113 |
cordic_z24 #(.bitwidth(24)) |
| 114 |
cordic(.clock(clk), .reset(rst), .enable(run), |
| 115 |
.xi(prod_i[23:0]),. yi(prod_q[23:0]), .zi(phase[31:8]), |
| 116 |
.xo(i_cordic),.yo(q_cordic),.zo() ); |
| 117 |
|
| 118 |
cic_strober cic_strober(.clock(clk),.reset(rst),.enable(run),.rate(cic_decim_rate), |
| 119 |
.strobe_fast(1),.strobe_slow(strobe_cic) ); |
| 120 |
|
| 121 |
cic_decim #(.bw(24)) |
| 122 |
decim_i (.clock(clk),.reset(rst),.enable(run), |
| 123 |
.rate(cic_decim_rate),.strobe_in(1'b1),.strobe_out(strobe_cic), |
| 124 |
.signal_in(i_cordic),.signal_out(i_cic)); |
| 125 |
|
| 126 |
cic_decim #(.bw(24)) |
| 127 |
decim_q (.clock(clk),.reset(rst),.enable(run), |
| 128 |
.rate(cic_decim_rate),.strobe_in(1'b1),.strobe_out(strobe_cic), |
| 129 |
.signal_in(q_cordic),.signal_out(q_cic)); |
| 130 |
|
| 131 |
round_reg #(.bits_in(24),.bits_out(18)) round_icic (.clk(clk),.in(i_cic),.out(i_cic_scaled)); |
| 132 |
round_reg #(.bits_in(24),.bits_out(18)) round_qcic (.clk(clk),.in(q_cic),.out(q_cic_scaled)); |
| 133 |
reg strobe_cic_d1; |
| 134 |
always @(posedge clk) strobe_cic_d1 <= strobe_cic; |
| 135 |
|
| 136 |
small_hb_dec #(.WIDTH(18)) small_hb_i |
| 137 |
(.clk(clk),.rst(rst),.bypass(~enable_hb1),.run(run), |
| 138 |
.stb_in(strobe_cic_d1),.data_in(i_cic_scaled),.stb_out(strobe_hb1),.data_out(i_hb1)); |
| 139 |
|
| 140 |
small_hb_dec #(.WIDTH(18)) small_hb_q |
| 141 |
(.clk(clk),.rst(rst),.bypass(~enable_hb1),.run(run), |
| 142 |
.stb_in(strobe_cic_d1),.data_in(q_cic_scaled),.stb_out(),.data_out(q_hb1)); |
| 143 |
|
| 144 |
wire [8:0] cpi_hb = enable_hb1 ? {cic_decim_rate,1'b0} : {1'b0,cic_decim_rate};
|
| 145 |
hb_dec #(.IWIDTH(18), .OWIDTH(18), .CWIDTH(18), .ACCWIDTH(24)) hb_i |
| 146 |
(.clk(clk),.rst(rst),.bypass(~enable_hb2),.run(run),.cpi(cpi_hb), |
| 147 |
.stb_in(strobe_hb1),.data_in(i_hb1),.stb_out(strobe_hb2),.data_out(i_hb2)); |
| 148 |
|
| 149 |
hb_dec #(.IWIDTH(18), .OWIDTH(18), .CWIDTH(18), .ACCWIDTH(24)) hb_q |
| 150 |
(.clk(clk),.rst(rst),.bypass(~enable_hb2),.run(run),.cpi(cpi_hb), |
| 151 |
.stb_in(strobe_hb1),.data_in(q_hb1),.stb_out(),.data_out(q_hb2)); |
| 152 |
|
| 153 |
round #(.bits_in(18),.bits_out(16)) round_iout (.in(i_hb2),.out(i_out)); |
| 154 |
round #(.bits_in(18),.bits_out(16)) round_qout (.in(q_hb2),.out(q_out)); |
| 155 |
|
| 156 |
// Streaming GPIO |
| 157 |
// |
| 158 |
// io_rx[15] => I channel LSB if gpio_ena[0] high |
| 159 |
// io_rx[14] => Q channel LSB if gpio_ena[1] high |
| 160 |
|
| 161 |
reg [31:0] sample_reg; |
| 162 |
always @(posedge clk) |
| 163 |
begin |
| 164 |
sample_reg[31:17] <= i_out[15:1]; |
| 165 |
sample_reg[15:1] <= q_out[15:1]; |
| 166 |
sample_reg[16] <= gpio_ena[0] ? io_rx[15] : i_out[0]; |
| 167 |
sample_reg[0] <= gpio_ena[1] ? io_rx[14] : q_out[0]; |
| 168 |
end |
| 169 |
|
| 170 |
assign sample = sample_reg; |
| 171 |
assign strobe = strobe_hb2; |
| 172 |
assign debug = {enable_hb1, enable_hb2, run, strobe, strobe_cic, strobe_cic_d1, strobe_hb1, strobe_hb2};
|
| 173 |
|
| 174 |
endmodule // dsp_core_rx |