// LLRF history buffers for EPICS // Larry Doolittle, LBNL, 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( clk40, rstn, dals, dbls, dcls, ddls, // input data and their clock outm, // option to monitor output channel trace_enable, dhistory_config, uhistory_config, dstop_count, ustop_count, dcnt_at_pulse_end, ucnt_at_pulse_end, test_buffers_config, clk_host, host_dout, host_addr, we); // host interface input clk40, rstn; input [11:0] dals, dbls, dcls, ddls, outm; input clk_host, we; output [15:0] host_dout; input [13:0] host_addr; input trace_enable; // valid in the 40 MHz clock domain input [15:0] dhistory_config, uhistory_config; // not necessarily all bits are used input [14:0] dstop_count, ustop_count; output [14:0] dcnt_at_pulse_end, ucnt_at_pulse_end; output test_buffers_config; wire test_buffers_config = 1'b0; wire [6:0] uaverage = uhistory_config[6:0]; wire [2:0] ukeep_mux = uhistory_config[10:8]; 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 [2:0] dkeep_mux = dhistory_config[10:8]; wire [0:0] traced_sel = dhistory_config[12:12]; reg [11:0] traced_data, trace1_data, trace2_data, trace3_data; wire [15:0] traced_dout, trace1_dout, trace2_dout, trace3_dout; wire dwrite_enable, uwrite_enable; wire davg_clear, uavg_clear; wire [8:0] dtrace_address, utrace_address; hist2 traced( clk40, traced_data, dtrace_address, dwrite_enable, davg_clear, dkeep_mux, clk_host, traced_dout, host_addr[8:0]); hist2 trace1( clk40, trace1_data, utrace_address, uwrite_enable, uavg_clear, ukeep_mux, clk_host, trace1_dout, host_addr[8:0]); hist2 trace2( clk40, trace2_data, utrace_address, uwrite_enable, uavg_clear, ukeep_mux, clk_host, trace2_dout, host_addr[8:0]); hist2 trace3( clk40, trace3_data, utrace_address, uwrite_enable, uavg_clear, ukeep_mux, clk_host, trace3_dout, host_addr[8:0]); histmode uhm( clk40, rstn, trace_enable, uaverage, ustop_count, utrace_address, uwrite_enable, uavg_clear, ucnt_at_pulse_end); histmode dhm( clk40, rstn, trace_enable, daverage, dstop_count, dtrace_address, dwrite_enable, davg_clear, dcnt_at_pulse_end); always @(posedge clk40 or negedge rstn) if (~rstn) 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] ? outm : dcls ; // Out or Cav end assign host_dout = ~host_addr[13] ? traced_dout // "decay" 0x0000 through 0x7ffc addressed, 0x4000 through 0x4ffc used : ( ~host_addr[12] ? ( ~host_addr[11] ? trace1_dout // "Fwd" 0x8000 through 0x9ffc addressed, 0x8000 through 0x87fc used : trace2_dout // "Rfl" 0xa000 through 0xbffc addressed, 0xa000 through 0xa7fc used ) : trace3_dout // "Field" 0xc000 through 0xfffc addressed, 0xc000 through 0xc7fc used ) ; endmodule