// afterburner.v
// Ultra-simple (2-tap) interpolating FIR filter
// $Id$
// Larry Doolittle, LBNL
// llc-suite Copyright (c) 2004, The Regents of the University of
// California, through Lawrence Berkeley National Laboratory (subject
// to receipt of any required approvals from the U.S. Dept. of Energy).
// All rights reserved.
// Your use of this software is pursuant to a "BSD-style" open
// source license agreement, the text of which is in license.txt
// (md5sum a1e0e81c78f6eba050b0e96996f49fd5) that should accompany
// this file. If the license agreement is not there, or if you
// have questions about the license, please contact Berkeley Lab's
// Technology Transfer Department at TTD@lbl.gov referring to
// "llc-suite (LBNL Ref CR-1988)"
// Input sig_in comes in clocked by clk40
// Output DE goes out clocked by clk80
// The single coefficient must be adjusted by the dkcm_bus.
// The nominal value for the LLRF system is -1.414, but other values
// are interesting for test purposes (e.g., +1.414 will deliver
// 10/70 MHz instead of 30/50 MHz output).
// You get a coefficient of -1.414 by pushing -1.414*1024 = -1448 into
// the 12-bit signed coefficient of dkcm.
// Proper phase relationship of clk40 and clk80 is essential.
// Input is assumed signed. Output is also signed, so the
// high order bit needs flipping before it actually gets sent
// to the DAC902.
`timescale 1ns / 1ns
module afterburner
(
input clk40, // interconnect
input [21:0] dkcm_bus, // interconnect
input host_clk, // interconnect
input [11:0] outsig40, // interconnect
input CLK80X, // pin a
output [11:0] DE // pin b
);
wire clk80;
BUFG u5(clk80, CLK80X);
wire [11:0] sig_in=outsig40;
reg [11:0] prev_sig_in, prev_product;
wire [23:0] product;
// sign-extend before adding
wire [12:0] average = {sig_in[11],sig_in} + {prev_sig_in[11],prev_sig_in};
// var, product, clk, dkcm_bus, ident
dkcm_bussed scale(average[12:1], product, host_clk, dkcm_bus, 3'b000);
always @(posedge clk40) begin
prev_sig_in <= sig_in;
// clip
prev_product <= ((product[23:21]==3'b000) | (product[23:21]==3'b111)) ?
product[21:10] :
(product[23]? 12'b100000000000 : 12'b011111111111 );
end
reg [11:0] ab_out;
always @(posedge clk80)
ab_out <= clk40 ? prev_product : prev_sig_in;
assign DE = {~ab_out[11], ab_out[10:0]};
endmodule