249 lines
8.3 KiB
Verilog
249 lines
8.3 KiB
Verilog
/******************************************************************************
|
|
* Copyright *
|
|
* Scintillating Fibre Beam Profile Monitor Software by Michal Dziewiecki, *
|
|
* Blake Leverington and Liqing Qin is licensed under CC BY 4.0 *
|
|
* https://creativecommons.org/licenses/by/4.0/ *
|
|
* funded by the Deutsche Forschungsgemeinschaft *
|
|
* (DFG, German Research Foundation) Projektnummer 419255448 *
|
|
* Project Leader: B.Leverington *
|
|
*******************************************************************************
|
|
* Create Date - Oct 15th. 2024 *
|
|
* Author: L.Qin *
|
|
* Module - calibration.v *
|
|
******************************************************************************/
|
|
/*Created by Lq.Qin on Oct 15th. 2024*/
|
|
|
|
//module calibration has two functions: calibration and merge 16-bit stream to 32-bit stream and then output
|
|
//calibration output 16-bit data_caled
|
|
//a better design is a design seperate these two functions
|
|
//tested by calibration_tb 25.07.2024
|
|
|
|
module calibration
|
|
(
|
|
|
|
input wire clk,
|
|
input wire rst, // connect to the data_in_startofpacket; to reset for everyframe
|
|
|
|
//avalon ST(Streaming) sink: 0 readlatency and 0 readallowence 320 channel
|
|
input wire signed[15:0] data_in_data, // st.data
|
|
output wire data_in_ready, // .ready
|
|
input wire data_in_valid, // .valid
|
|
input wire data_in_empty, // .empty
|
|
input wire data_in_endofpacket, // .endofpacket
|
|
input wire data_in_startofpacket, // .startofpacket
|
|
|
|
//the interface with cali_ram (storing cali factor) Avalon-MM: read califac from this ram
|
|
output wire [8:0] address,
|
|
output wire clken, //read
|
|
input wire [15:0] cali_fac,
|
|
input wire waitrequest,
|
|
|
|
//the interface for provide the calibrated data in a ram // one clock latency
|
|
input wire [8:0] data_caled_address,
|
|
output wire [15:0] data_caled,
|
|
input wire data_caled_rd_enable, // to enable read
|
|
|
|
output wire data_in_last, //....
|
|
|
|
//avalon ST(Streaming) source: 0 readlatency and 0 readallowence //160 * 32 bits data
|
|
// channel 0 [31:16] channel 1 [15:0]
|
|
output wire [31:0] to_udp_data, // st.data
|
|
input wire to_udp_ready, // .ready
|
|
output wire to_udp_valid, // .valid
|
|
output wire [1:0] to_udp_empty, // .empty
|
|
output wire to_udp_endofpacket, // .endofpacket
|
|
output wire to_udp_startofpacket // .startofpacket
|
|
);
|
|
|
|
assign data_in_last = data_in_endofpacket;
|
|
|
|
localparam SHIFT_BIT = 13; //2^13 = 8192, the calibration factor 1 is represented by 8192
|
|
|
|
//for to_udp_data
|
|
reg [15:0] first_data_buffer;
|
|
|
|
//for read calibration ram
|
|
reg [8:0] read_cali_address;
|
|
reg signed[16:0] cali_fac_buffer;
|
|
wire read;
|
|
assign clken = read;
|
|
assign address = read_cali_address;
|
|
|
|
//for write and read the calibrated data
|
|
reg signed[31:0] data_caled_data_32bit;
|
|
wire data_caled_wren_a;
|
|
reg [8:0] data_caled_address_a;
|
|
wire [8:0] address_b;
|
|
assign address_b = (data_caled_rd_enable)? data_caled_address: 9'd0;
|
|
wire[15:0] data_caled_data_a;
|
|
assign data_caled_data_a = {data_caled_data_32bit[31],data_caled_data_32bit[14+SHIFT_BIT:SHIFT_BIT]};
|
|
|
|
|
|
data_caled_ram data_caled_ram0 (
|
|
|
|
.clock ( clk ),
|
|
|
|
.address_a (data_caled_address_a),
|
|
.data_a (data_caled_data_a),
|
|
.wren_a (data_caled_wren_a),
|
|
.q_a ( ),
|
|
|
|
.address_b ( address_b ),
|
|
.data_b ( ),
|
|
.wren_b (1'b0),
|
|
.q_b ( data_caled)
|
|
);
|
|
|
|
//the state machine for read calibration factor from ram
|
|
reg[3:0] state;
|
|
localparam STATE_IDLE = 4'd0; //waiting for startofpacket
|
|
localparam STATE_CAL0 = 4'd1; //get califactor for channel0
|
|
localparam STATE_INPUT0 = 4'd2; // stream in data for channel0;
|
|
localparam STATE_CAL1 = 4'd3; // get califactor for channel1
|
|
localparam STATE_INPUT1 = 4'd4; // stream in data for channel1;
|
|
localparam STATE_CAL2 = 4'd5; //get califactor for channel1; output the first 32-bit udp data [channel0, channel1]
|
|
localparam STATE_INPUT_EVEN = 4'd6; // stream in data for channel 2,4,6.....
|
|
localparam STATE_CAL_ODD = 4'd7;
|
|
localparam STATE_INPUT_ODD = 4'd8;
|
|
localparam STATE_CAL_EVEN = 4'd9;
|
|
localparam STATE_OUTPUT_LAST = 4'd10; //outout the last 32-bit udp data
|
|
|
|
|
|
assign data_in_ready = (state == STATE_INPUT0 || state == STATE_INPUT1 || state == STATE_INPUT_EVEN || state == STATE_INPUT_ODD)?1'b1:1'b0;
|
|
assign data_caled_wren_a = (state == STATE_CAL1 || state == STATE_CAL2 || state == STATE_CAL_EVEN || state == STATE_CAL_ODD || state == STATE_OUTPUT_LAST)?1'b1:1'b0;
|
|
assign read = (state == STATE_CAL0 ||state == STATE_CAL1 || state == STATE_CAL2 || state == STATE_CAL_EVEN || state == STATE_CAL_ODD)?1'b1:1'b0;
|
|
|
|
|
|
|
|
always @ (posedge clk or posedge rst)
|
|
begin
|
|
if (rst)
|
|
begin
|
|
state <= STATE_IDLE;
|
|
data_caled_address_a <= 0;
|
|
read_cali_address <= 0;
|
|
end
|
|
else case(state)
|
|
STATE_IDLE:
|
|
begin
|
|
data_caled_address_a <= 0;
|
|
read_cali_address <= 0;
|
|
if (data_in_startofpacket)
|
|
begin
|
|
state <= STATE_CAL0;
|
|
end
|
|
end
|
|
STATE_CAL0:
|
|
begin
|
|
if (~waitrequest) begin
|
|
cali_fac_buffer <= {1'b0,cali_fac};
|
|
state <= STATE_INPUT0;
|
|
end
|
|
end
|
|
STATE_INPUT0:
|
|
begin
|
|
if (data_in_valid)
|
|
begin
|
|
first_data_buffer <= 16'd0;
|
|
data_caled_data_32bit <= data_in_data*cali_fac_buffer;
|
|
//data_caled_data_32bit <= cali_fac_buffer;// test! cali
|
|
read_cali_address <= read_cali_address + 1'b1;
|
|
state <= STATE_CAL1;
|
|
end
|
|
end
|
|
STATE_CAL1:
|
|
begin
|
|
if (~waitrequest) begin
|
|
cali_fac_buffer <= {1'b0,cali_fac};
|
|
state <= STATE_INPUT1;
|
|
end
|
|
end
|
|
STATE_INPUT1:
|
|
begin
|
|
if (data_in_valid)
|
|
begin
|
|
first_data_buffer <= data_caled_data_a;
|
|
data_caled_data_32bit <= data_in_data*cali_fac_buffer;
|
|
//data_caled_data_32bit <= cali_fac_buffer;// test! cali
|
|
read_cali_address <= read_cali_address + 1'b1;
|
|
data_caled_address_a <= data_caled_address_a + 1'b1;
|
|
state <= STATE_CAL2;
|
|
end
|
|
end
|
|
STATE_CAL2:
|
|
begin
|
|
if (~waitrequest & to_udp_ready) begin
|
|
cali_fac_buffer <= {1'b0,cali_fac};
|
|
state <= STATE_INPUT_EVEN;
|
|
end
|
|
end
|
|
STATE_INPUT_EVEN:
|
|
begin
|
|
if (data_in_valid)
|
|
begin
|
|
data_caled_data_32bit <= data_in_data*cali_fac_buffer;
|
|
//data_caled_data_32bit <= cali_fac_buffer;// test! cali
|
|
first_data_buffer <= 16'd0;
|
|
read_cali_address <= read_cali_address + 1'b1;
|
|
data_caled_address_a <= data_caled_address_a + 1'b1;
|
|
if (data_in_endofpacket)
|
|
state <= STATE_OUTPUT_LAST;
|
|
else
|
|
state <= STATE_CAL_ODD;
|
|
end
|
|
end
|
|
STATE_CAL_ODD:
|
|
begin
|
|
if (~waitrequest) begin
|
|
cali_fac_buffer <= {1'b0,cali_fac};
|
|
state <= STATE_INPUT_ODD;
|
|
end
|
|
end
|
|
STATE_INPUT_ODD:
|
|
begin
|
|
if (data_in_valid)
|
|
begin
|
|
first_data_buffer <= data_caled_data_a;
|
|
data_caled_data_32bit <= data_in_data*cali_fac_buffer;
|
|
//data_caled_data_32bit <= cali_fac_buffer;// test! cali
|
|
read_cali_address <= read_cali_address + 1'b1;
|
|
data_caled_address_a <= data_caled_address_a + 1'b1;
|
|
if (data_in_endofpacket)
|
|
state <= STATE_OUTPUT_LAST;
|
|
else
|
|
state <= STATE_CAL_EVEN;
|
|
end
|
|
end
|
|
STATE_CAL_EVEN:
|
|
begin
|
|
if (~waitrequest & to_udp_ready) begin
|
|
cali_fac_buffer <= {1'b0,cali_fac};
|
|
state <= STATE_INPUT_EVEN;
|
|
end
|
|
end
|
|
STATE_OUTPUT_LAST:
|
|
begin
|
|
if (to_udp_ready)
|
|
state <= STATE_IDLE;
|
|
end
|
|
default:
|
|
state <= STATE_IDLE;
|
|
endcase
|
|
end
|
|
|
|
|
|
//output the 160 32bit words to upd, first channel [31:16] , second channel [15:16]
|
|
//output wire [31:0] to_udp_data, // st.data
|
|
assign to_udp_valid = (((state == STATE_CAL2 || state == STATE_CAL_EVEN) && (~waitrequest))|| state == STATE_OUTPUT_LAST)? 1'b1: 1'b0;
|
|
assign to_udp_empty = 2'b0;
|
|
assign to_udp_startofpacket = (state == STATE_CAL2 && (~waitrequest))? 1'b1:1'b0;
|
|
assign to_udp_endofpacket = (state == STATE_OUTPUT_LAST)? 1'b1: 1'b0;
|
|
//reverse the polarity for output => no for simulation
|
|
assign to_udp_data = (((state == STATE_CAL2 || state == STATE_CAL_EVEN) && (~waitrequest))|| state == STATE_OUTPUT_LAST) ? {~first_data_buffer,~data_caled_data_a}: 32'b0;
|
|
|
|
|
|
|
|
|
|
|
|
endmodule
|