// LLRF history buffers for test // Larry Doolittle, LBNL, March 2003 // Mostly an instantiation of a bunch of dual port RAMs, but also // includes address generation and data multiplexing on the ADC end, // and a little bit of data multiplexing for host read of the data. // 2 buffers, 2K x 14, programmable averaging `timescale 1ns / 1ns module history2k( clk40, rstn, dals, dbls, dcls, ddls, // input data and their clock outm, // option to monitor output channel trace_enable, address_at_pulse_end, history_config, 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 output [15:0] address_at_pulse_end; input [15:0] history_config; // not necessarily all bits are used output test_buffers_config; wire write_enable = trace_enable; wire [1:0] average = history_config[1:0]; wire [1:0] trace1_sel = history_config[9:8]; wire [1:0] trace2_sel = history_config[11:10]; wire test_buffers_config = 1'b1; reg [11:0] trace1_data, trace2_data; wire [13:0] trace1_dout, trace2_dout; reg [15:0] address_at_pulse_end; reg [3:0] countl; reg [8:0] counth; wire clear = countl[3:2] == 2'b00; wire carry = countl == {average, 2'b11}; wire [10:0] trace_address = {counth, countl[1:0]}; hist4 trace1( clk40, trace1_data, trace_address, write_enable, clear, clk_host, trace1_dout, host_addr[11:0]); hist4 trace2( clk40, trace2_data, trace_address, write_enable, clear, clk_host, trace2_dout, host_addr[11:0]); always @(posedge clk40 or negedge rstn) if (!rstn) begin trace1_data <= 0; trace2_data <= 0; countl <= 0; counth <= 0; address_at_pulse_end <= 0; end else begin // Ordinary multiplexer; a bank of SRL16E's could be used instead // to reduce the cell footprint, at the expense of more arcane // Verilog and more awkward host software. trace1_data <= trace1_sel[1] ? ( trace1_sel[0] ? ddls : dcls ) : ( trace1_sel[0] ? dbls : dals ); trace2_data <= trace2_sel[1] ? ( trace2_sel[0] ? ddls : dcls ) : ( trace2_sel[0] ? dbls : dals ); countl <= (carry | ~trace_enable) ? 0 : (countl + 1'b1); counth <= trace_enable ? (carry ? (counth + 1'b1) : counth) : 0; if (trace_enable) address_at_pulse_end <= {5'b0000, trace_address}; end assign host_dout = ~host_addr[12] ? {2'b00, trace1_dout } // 0x8000 through 0x9ffc : {2'b00, trace2_dout } // 0xc000 through 0xdfff ; endmodule