// history2e.v
// LLRF history buffers for EPICS
// $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)"
// Initial coding March 2003
// 4 buffers, 512 x 16, programmable averaging
// Three of these buffers are considered "user" configured for operator
// comfort display or troubleshooting.
// One more is considered a "decay" buffer, configured for automated
// analysis of cavity resonance frequency.
// Hence the matched set of d* and u* variables.
// The two timing controllers (histmode) and four averaging history buffers
// (hist2) are instantiated. All this module takes care of is fan-out,
// fan-in (multiplexing data back to the host), and choosing which data
// streams to route to each history buffer.
`timescale 1ns / 1ns
module history2e
(
input rst, // interconnect
input host_clk, // interconnect
input [13:0] host_addr, // interconnect
output [15:0] traced_dout, // register TRACED
output [15:0] trace1_dout, // register TRACE1
output [15:0] trace2_dout, // register TRACE2
output [15:0] trace3_dout, // register TRACE3
input clk40, // interconnect
input [`RAW_ADC_BITS-1:0] DA, // pin a
input [`RAW_ADC_BITS-1:0] DB, // pin b
input [`RAW_ADC_BITS-1:0] DC, // pin c
input [`RAW_ADC_BITS-1:0] DD, // pin d
input [11:0] outsig40, // interconnect
output [13:0] fdbk_input, // interconnect
input totalizer_channel, // interconnect
output [13:0] totalizer_in, // interconnect
input [14:0] ustop_count, // register USTOP_CNT
input [15:0] uhistory_config, // register UHIST_CFG
input [14:0] dstop_count, // register DSTOP_CNT
input [15:0] dhistory_config, // register DHIST_CFG
output [14:0] ucnt_at_pulse_end, // register UCAPE
output [14:0] dcnt_at_pulse_end, // register DCAPE
input trace_enable // interconnect
);
wire [6:0] uaverage = uhistory_config[6:0];
wire [0:0] trace1_sel = uhistory_config[12:12];
wire [0:0] trace2_sel = uhistory_config[13:13];
wire [0:0] trace3_sel = uhistory_config[14:14];
wire [6:0] daverage = dhistory_config[6:0];
wire [0:0] traced_sel = dhistory_config[12:12];
reg [`RAW_ADC_BITS-1:0] traced_data, trace1_data, trace2_data, trace3_data;
wire dwrite_enable, uwrite_enable;
wire davg_clear, uavg_clear;
wire [`ADDRESS_BITS-1:0] dtrace_address, utrace_address;
reg [`RAW_ADC_BITS-1:0] dal, dbl, dcl, ddl; // Latched input from ADCs
always @(posedge clk40) begin
// The following 48 latches should be absorbed into IOBs:
dal <= DA; dbl <= DB; dcl <= DC; ddl <= DD;
end
wire [`RAW_ADC_BITS-1:0] dals, dbls, dcls, ddls; // Latched and converted (if necessary) to signed binary
`ifdef ADC_IS_SIGNED
wire [`RAW_ADC_BITS-1:0] flipper = {1'b0, {`RAW_ADC_BITS-1{1'b0}}};
`else
wire [`RAW_ADC_BITS-1:0] flipper = {1'b1, {`RAW_ADC_BITS-1{1'b0}}};
`endif
assign dals = dal ^ flipper;
assign dbls = dbl ^ flipper;
assign dcls = dcl ^ flipper;
assign ddls = ddl ^ flipper;
`ifdef ADC_BIT12
wire [`RAW_ADC_BITS-1:0] outm = outsig40; // rename
assign fdbk_input = {dcls,2'b00}; // pad from 12 to 14 bits
assign totalizer_in = {(totalizer_channel ? dcls : ddls),2'b00}; // channel selection for phase ref
`else
wire [`RAW_ADC_BITS-1:0] outm = {outsig40,2'b00}; // pad from 12 to 14 bits
assign fdbk_input = dcls; // channel selection for feedback input
assign totalizer_in = totalizer_channel ? dcls : ddls; // channel selection for phase ref
`endif
hist2 traced(
clk40, traced_data, dtrace_address, dwrite_enable, davg_clear, daverage,
host_clk, traced_dout, host_addr[`ADDRESS_BITS-1:0]);
hist2 trace1(
clk40, trace1_data, utrace_address, uwrite_enable, uavg_clear, uaverage,
host_clk, trace1_dout, host_addr[`ADDRESS_BITS-1:0]);
hist2 trace2(
clk40, trace2_data, utrace_address, uwrite_enable, uavg_clear, uaverage,
host_clk, trace2_dout, host_addr[`ADDRESS_BITS-1:0]);
hist2 trace3(
clk40, trace3_data, utrace_address, uwrite_enable, uavg_clear, uaverage,
host_clk, trace3_dout, host_addr[`ADDRESS_BITS-1:0]);
histmode uhm(
clk40, rst, trace_enable, uaverage, ustop_count,
utrace_address, uwrite_enable, uavg_clear, ucnt_at_pulse_end);
histmode dhm(
clk40, rst, trace_enable, daverage, dstop_count,
dtrace_address, dwrite_enable, davg_clear, dcnt_at_pulse_end);
always @(posedge clk40 or posedge rst) if (rst) begin
traced_data <= 0;
trace1_data <= 0;
trace2_data <= 0;
trace3_data <= 0;
end else begin
traced_data <= traced_sel[0] ? dbls : dcls ; // Rfl or Cav
trace1_data <= trace1_sel[0] ? ddls : dals ; // Ref or Fwd
trace2_data <= trace2_sel[0] ? outm : dbls ; // Out or Rfl
trace3_data <= trace3_sel[0] ? ddls : dcls ; // Ref or Cav
end
endmodule