util_cic: Allow partial gating of CIC comb and int stages
Allow to split a CIC int or comb block into multiple stages and be able to dynamically gate some of the stages. Also prevent carry propagation in gated stages to keep the adder output constant. This is useful for multi-rate filter where not all bits are needed all the time. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>main
parent
3e7325b29a
commit
17dff9ce90
|
@ -37,10 +37,13 @@
|
||||||
|
|
||||||
module cic_comb #(
|
module cic_comb #(
|
||||||
parameter DATA_WIDTH = 32,
|
parameter DATA_WIDTH = 32,
|
||||||
parameter SEQ = 1
|
parameter SEQ = 1,
|
||||||
|
parameter STAGE_WIDTH = 1,
|
||||||
|
parameter NUM_STAGES = 1
|
||||||
) (
|
) (
|
||||||
input clk,
|
input clk,
|
||||||
input ce,
|
input ce,
|
||||||
|
input [NUM_STAGES-1:0] enable,
|
||||||
input [DATA_WIDTH-1:0] data_in,
|
input [DATA_WIDTH-1:0] data_in,
|
||||||
output [DATA_WIDTH-1:0] data_out
|
output [DATA_WIDTH-1:0] data_out
|
||||||
);
|
);
|
||||||
|
@ -76,8 +79,10 @@ end
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
|
wire [DATA_WIDTH-1:0] mask;
|
||||||
reg [DATA_WIDTH-1:0] data_in_seq;
|
reg [DATA_WIDTH-1:0] data_in_seq;
|
||||||
wire [DATA_WIDTH-1:0] storage_out;
|
wire [DATA_WIDTH-1:0] storage_out;
|
||||||
|
wire [DATA_WIDTH-1:0] diff = (data_in_seq | ~mask) - (storage_out & mask);
|
||||||
|
|
||||||
always @(*) begin
|
always @(*) begin
|
||||||
if (ce == 1'b1) begin
|
if (ce == 1'b1) begin
|
||||||
|
@ -87,18 +92,19 @@ always @(*) begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if (ce == 1'b1 || active == 1'b1) begin
|
|
||||||
state <= data_in_seq - storage_out;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
generate
|
generate
|
||||||
genvar i;
|
genvar i, j;
|
||||||
|
|
||||||
for (i = 0; i < DATA_WIDTH; i = i + 1) begin: shift_r
|
for (j = 0; j < NUM_STAGES; j = j + 1) begin
|
||||||
|
localparam k = NUM_STAGES - j - 1;
|
||||||
|
localparam H = DATA_WIDTH - STAGE_WIDTH * j - 1;
|
||||||
|
localparam L = k == 0 ? 0 : DATA_WIDTH - STAGE_WIDTH * (j+1);
|
||||||
|
|
||||||
|
assign mask[H:L] = {{H-L{1'b1}},k != 0 ? enable[k] : 1'b1};
|
||||||
|
|
||||||
|
for (i = L; i <= H; i = i + 1) begin: shift_r
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (ce == 1'b1 || active == 1'b1) begin
|
if (enable[k] == 1'b1 && (ce == 1'b1 || active == 1'b1)) begin
|
||||||
if (SEQ > 1) begin
|
if (SEQ > 1) begin
|
||||||
storage[i] <= {storage[i][SEQ-2:0],data_in_seq[i]};
|
storage[i] <= {storage[i][SEQ-2:0],data_in_seq[i]};
|
||||||
end else begin
|
end else begin
|
||||||
|
@ -108,7 +114,16 @@ generate
|
||||||
end
|
end
|
||||||
|
|
||||||
assign storage_out[i] = storage[i][SEQ-1];
|
assign storage_out[i] = storage[i][SEQ-1];
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (enable[k] == 1'b1 && (ce == 1'b1 || active == 1'b1)) begin
|
||||||
|
state[H:L] <= diff[H:L];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
assign data_out = state;
|
assign data_out = state;
|
||||||
|
|
|
@ -36,24 +36,39 @@
|
||||||
// ***************************************************************************
|
// ***************************************************************************
|
||||||
|
|
||||||
module cic_int #(
|
module cic_int #(
|
||||||
parameter DATA_WIDTH = 12
|
parameter DATA_WIDTH = 12,
|
||||||
|
parameter STAGE_WIDTH = 1,
|
||||||
|
parameter NUM_STAGES = 1
|
||||||
) (
|
) (
|
||||||
input clk,
|
input clk,
|
||||||
input ce,
|
input [NUM_STAGES-1:0] ce,
|
||||||
input [DATA_WIDTH-1:0] data_in,
|
input [DATA_WIDTH-1:0] data_in,
|
||||||
output [DATA_WIDTH-1:0] data_out
|
output [DATA_WIDTH-1:0] data_out
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [DATA_WIDTH-1:0] state = 'h00;
|
reg [DATA_WIDTH-1:0] state = 'h00;
|
||||||
wire [DATA_WIDTH-1:0] sum;
|
wire [DATA_WIDTH-1:0] sum;
|
||||||
|
wire [DATA_WIDTH-1:0] mask;
|
||||||
|
|
||||||
assign data_out = state;
|
assign data_out = state;
|
||||||
assign sum = data_in + state;
|
assign sum = (data_in & mask) + (state & mask);
|
||||||
|
generate
|
||||||
|
genvar i;
|
||||||
|
|
||||||
|
for (i = 0; i < NUM_STAGES; i = i + 1) begin
|
||||||
|
localparam j = NUM_STAGES - i - 1;
|
||||||
|
localparam H = DATA_WIDTH - STAGE_WIDTH * i - 1;
|
||||||
|
localparam L = j == 0 ? 0 : DATA_WIDTH - STAGE_WIDTH * (i+1);
|
||||||
|
|
||||||
|
assign mask[H:L] = {{H-L{1'b1}},j != 0 ? ce[j] : 1'b1};
|
||||||
|
|
||||||
always @(posedge clk) begin
|
always @(posedge clk) begin
|
||||||
if (ce == 1'b1) begin
|
if (ce[j] == 1'b1) begin
|
||||||
state <= sum;
|
state[H:L] <= sum[H:L];
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
endgenerate
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue