blob: 8670ada63811ca5a3938696833169c6c87070bb2 [file] [log] [blame]
// 8-Tap Even Symmetric Systolic FIR
//
// Source:
// https://www.xilinx.com/support/documentation/sw_manuals/xilinx2014_2/ug901-vivado-synthesis.pdf p.93
//
(* top *)
module ug901b #(parameter nbtap = 4, dsize = 16, psize = 2*dsize) (
input clk,
input signed [dsize-1:0] datain,
output signed [2*dsize-1:0] firout
);
wire signed [dsize-1:0] h [nbtap-1:0];
wire signed [dsize-1:0] arraydata [nbtap-1:0];
wire signed [psize-1:0] arrayprod [nbtap-1:0];
wire signed [dsize-1:0] shifterout;
reg signed [dsize-1:0] dataz [nbtap-1:0];
assign h[0] = 7;
assign h[1] = 14;
assign h[2] = -138;
assign h[3] = 129;
assign firout = arrayprod[nbtap-1]; // Connect last product to output
sfir_shifter #(dsize, nbtap) shifter_inst0 (
clk,
datain,
shifterout);
generate
genvar I;
for (I=0; I<nbtap; I=I+1)
if (I==0)
sfir_even_symmetric_systolic_element #(dsize) fte_inst0 (
clk,
h[I],
datain,
shifterout,
{32{1'b0}},
arraydata[I],
arrayprod[I]);
else
sfir_even_symmetric_systolic_element #(dsize) fte_inst (
clk,
h[I],
arraydata[I-1],
shifterout,
arrayprod[I-1],
arraydata[I],
arrayprod[I]);
endgenerate
endmodule
(* gentb_skip *) // Prevents Yosys' test_autotb from operating on this module
(* dont_touch = "yes" *)
module sfir_shifter #(parameter dsize = 16, nbtap = 4) (
input clk,
input [dsize-1:0] datain,
output [dsize-1:0] dataout
);
(* srl_style = "srl_register" *) reg [dsize-1:0] tmp [0:2*nbtap-1];
integer i;
always @(posedge clk)
begin
tmp[0] <= datain;
for (i=0; i<=2*nbtap-2; i=i+1)
tmp[i+1] <= tmp[i];
end
assign dataout = tmp[2*nbtap-1];
endmodule
(* gentb_skip *) // Prevents Yosys' test_autotb from operating on this module
module sfir_even_symmetric_systolic_element #(parameter dsize = 16) (
input clk,
input signed [dsize-1:0] coeffin, datain, datazin,
input signed [2*dsize-1:0] cascin,
output signed [dsize-1:0] cascdata,
output reg signed [2*dsize-1:0] cascout
);
reg signed [dsize-1:0] coeff;
reg signed [dsize-1:0] data;
reg signed [dsize-1:0] dataz;
reg signed [dsize-1:0] datatwo;
reg signed [dsize:0] preadd;
reg signed [2*dsize-1:0] product;
assign cascdata = datatwo;
always @(posedge clk)
begin
coeff <= coeffin;
data <= datain;
datatwo <= data;
dataz <= datazin;
preadd <= datatwo + dataz;
product <= preadd * coeff;
cascout <= product + cascin;
end
endmodule
`ifndef _AUTOTB
module __test ;
wire [4095:0] assert_area = "cd ug901b; flatten; select t:DSP48E1 -assert-count 4; select t:FDRE -assert-count 128; select t:SRL16E -assert-count 16; select -assert-none t:DSP48E1 t:BUFG t:FDRE t:SRL16E %% t:* %D";
endmodule
`endif