📄 top_vhd_t.v
字号:
////////////////////////////////////////////////////////////////////////////////////////////////////// Serial to Parallel Convertor//// This module takes multiple serial data streams, which are bit-synchronous with each other,// and converts the data to a parallel words.//// Several constants are declared in the WORK1.SER_PAR_LIB library, including the number of serial ports// to be converted and ENABLE_WRITE_STALL and ENABLE_READ_STALL. The user must determine the input bit rate// the output bit rate and the appropriate side to stall when one side cannot keep up with the other.//// The design takes heavy use of Virtex\'s LUT based shift registers and Distributed Dual Port RAM.//// The Dual Port Rams are used to double buffer the incomming data, as well as parallelize the data.// Data is written into one half of the memory, in a bit-wise fasion, while it is read out of the other// half of the memory in a parallel fashion. A ping-ponging of the memory occurs as one half emptys and // the other half fills, with the end result being that the reads now occur in the half just written, and // the writes now occur in the half just read. It takes 32 Slices, or 16 CLBs to store and double buffer // 8 channels of 32 bit data. Using a traditional shift register-latch approach would require (8 * 32 * 2 =) 512// flip flops, which is 256 slices or 128 CLBs. Some of this savings is lost due to some additional over-// head. //// The Shift Register LUTs are used to create effient delay lines which are used to create time-skewed// versions of the input data, such that an 8-bit word is available for writting into the dual port memories.// The incomming data is arranged into groups of 8, which then run through a delay line structure, is steered
// by eight 8 to one muxes, and then flows into the dual-port memory structure discused above.//// Each port position in each group of eight has a different delay, from 0 to seven clocks. Thus at any// given time, a different bit-number is available from each port. For example, assuming port 0 has a delay// of zero, port 1 has a delay of one, and so on. After seven clocks, the data at the output of the port 0 delay// line is bit 7, whereas the data at the output of the port 1 delay line is bit 6, down to bit 0 available at// port 7. The dual ports are arranged so that each dual port holds all the bit N\'s for all of the 8 channels.// Thus with the data skewed, we can write to 8 dual ports simultaneously. The delay lines require a total of 8// LUTs, or 4 slices which translates into 2 CLBS per 8 channels.//module TOP_VHD (SERIAL_DATA, WRITE_ENABLE_IN, WCLK, RCLK, RESET, WRITE_ENABLE_OUT, READ_ENABLE_OUT, READ_COUNT_OUT, INCREMENT_BCOUNT, DECREMENT_BCOUNT, DATA);
`include "parameter_file.v"
input[NUMBER_OF_SERIAL_PORTS - 1:0] SERIAL_DATA; input WRITE_ENABLE_IN; input WCLK; input RCLK; input RESET; output WRITE_ENABLE_OUT; wire WRITE_ENABLE_OUT; output READ_ENABLE_OUT; wire READ_ENABLE_OUT; output [7:0] READ_COUNT_OUT; output INCREMENT_BCOUNT; wire INCREMENT_BCOUNT; output DECREMENT_BCOUNT; wire DECREMENT_BCOUNT; output[31:0] DATA; wire[31:0] DATA; wire RD_CLK; wire WR_CLK; wire [23:0] WRITE_ADDRESS; wire[31:0] DP_WR_EN; wire[3:0] WA_MSB; wire[(NUMBER_OF_BANKS - 1):0] OE; wire DECREMENT_BCOUNT_INT; wire INCREMENT_BCOUNT_INT; wire READ_ENABLE; wire WRITE_ENABLE; reg [7:0] SERIAL_DATA_VECTORS [NUMBER_OF_BANKS-1:0]; wire[NUMBER_OF_BANKS - 1:0] TEMP_ADDRESS_ADJUST_MASK; wire FORCE_RD_ADDRESS_INC; wire [31:0] DATA_ARRAY [63:0];
reg [2047:0] DATA_UNARRAY; wire[31:0] DATA_BANK; assign WRITE_ENABLE_OUT = WRITE_ENABLE ; assign INCREMENT_BCOUNT = INCREMENT_BCOUNT_INT ; assign DECREMENT_BCOUNT = DECREMENT_BCOUNT_INT ;
assign ZERO_32 = 32'b00000000000000000000000000000000;
reg[(NUMBER_OF_BANKS)-1:0] TEMP_MASK;
reg[(NUMBER_OF_BANKS)-1:0] CREATE_MASK; reg[(8 * NUMBER_OF_BANKS) - 1:0] TEMP_SERIAL;
integer I;
integer J;
always
begin
for (I=0; I < 64; I = I + 1) begin
if (I <= NUMBER_OF_BANKS - 1) begin
for(J=0; J < 32; J = J + 1) begin
DATA_UNARRAY[(I*32)+J] = DATA_ARRAY[I][J];
end
end
else begin
for(J=0; J < 32; J = J + 1) begin
DATA_UNARRAY[(I*32)+J] = 1'b0;
end end
end
end
always
begin if ((NUMBER_OF_SERIAL_PORTS % 8) == 0) begin for(I = 0; I <= NUMBER_OF_BANKS - 1; I = I + 1) begin TEMP_MASK[I] = 1'b0; end CREATE_MASK = TEMP_MASK; end else begin for(I = 0; I <= (NUMBER_OF_SERIAL_PORTS - (7 * NUMBER_OF_BANKS) - 1); I = I + 1) begin TEMP_MASK[I] = 1'b0; end for(I = (NUMBER_OF_SERIAL_PORTS - (7 * NUMBER_OF_BANKS)); I <= (NUMBER_OF_BANKS - 1); I = I + 1) begin TEMP_MASK[I] = 1'b1; end CREATE_MASK = TEMP_MASK; end
end
assign TEMP_ADDRESS_ADJUST_MASK = CREATE_MASK ;
always
begin if ((NUMBER_OF_SERIAL_PORTS % 8) == 0) begin TEMP_SERIAL = SERIAL_DATA; end else begin TEMP_SERIAL[NUMBER_OF_SERIAL_PORTS - 1:0] = SERIAL_DATA; begin : xhdl_5 integer I; for(I = (8 * NUMBER_OF_BANKS) - 1; I <= NUMBER_OF_SERIAL_PORTS; I = I + 1) begin TEMP_SERIAL[I] = 1'b0; end end
end
begin : xhdl_6 integer I; for(I = 0; I <= (NUMBER_OF_BANKS - 1); I = I + 1) begin begin : xhdl_7 integer J; for(J = 0; J <= 7; J = J + 1) begin SERIAL_DATA_VECTORS[I][J] <= TEMP_SERIAL[(I * NUMBER_OF_BANKS) + J];
end end end
end end
WR_CNTRL WRITE_CNTRL1 (.DP_WR_EN(DP_WR_EN), .WA_MSB(WA_MSB), .WRITE_ADDRESS(WRITE_ADDRESS), .INCREMENT_BCOUNT(INCREMENT_BCOUNT_INT), .CLK(WR_CLK), .RESET(RESET), .WRITE_ENABLE(WRITE_ENABLE));
BUFG GLOBAL_RCLK1 (.I(RCLK), .O(RD_CLK));
BUFG GLOBAL_WCLK1 (.I(WCLK), .O(WR_CLK)); RD_CNTRL READ_CTRL1(.RESET(RESET), .CLK(RD_CLK), .READ_ENABLE(READ_ENABLE), .READ_COUNT(READ_COUNT_OUT), .DECREMENT_BCOUNT(DECREMENT_BCOUNT_INT), .FORCE_RD_ADDRESS_INC(FORCE_RD_ADDRESS_INC), .OE(OE)); SYNC SYNC1(.RESET(RESET), .RD_CLK(RD_CLK), .WR_CLK(WR_CLK), .DECREMENT_BCOUNT(DECREMENT_BCOUNT_INT), .INCREMENT_BCOUNT(INCREMENT_BCOUNT_INT), .ENABLE_IN(WRITE_ENABLE_IN), .WRITE_ENABLE(WRITE_ENABLE), .READ_ENABLE(READ_ENABLE)); OUTPUT_PIPELINE OUTPIPE1(.DATA_IN(DATA_UNARRAY), .READ_ENABLE(READ_ENABLE), .READ_ENABLE_OUT(READ_ENABLE_OUT), .RD_CLK(RD_CLK), .DATA_OUT(DATA));
genvar j; generate for (j=0; j <= (NUMBER_OF_BANKS-1); j=j+1) begin: SP2P8x32_loop S2P8X32 SP2P8x32_comp (.SERIAL_DATA(SERIAL_DATA_VECTORS[j][7:0]), .WRITE_ADDRESS(WRITE_ADDRESS), .DP_WR_EN(DP_WR_EN), .MSB_WR(WA_MSB), .OE(OE[j]), .DATA_BANK_OUT(DATA_ARRAY[j][31:0]), .ADJUST_ADDRESS_MASK(TEMP_ADDRESS_ADJUST_MASK[j]), .WR_CLK(WR_CLK), .WRITE_ENABLE(WRITE_ENABLE), .FORCE_RD_ADDRESS_INC(FORCE_RD_ADDRESS_INC), .RESET(RESET), .READ_ENABLE(READ_ENABLE), .RD_CLK(RD_CLK));
end endgenerate
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -