beginner_EDA
Full Member level 4
- Joined
- Aug 14, 2013
- Messages
- 191
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,296
- Activity points
- 3,854
Collect two or three inputs then write them to a 32 bit wide fifo. Fill the unused input data bits with 0.Then I am just wasting 32-10=22 bit width of full speed/load of Ethernet. In other word, It will be just increasing redundancy.
Any other suggestions, please.
I don't really know what you mean by full speed of Ethernet...see below. I'll assume you are using GigE.My aim is to connect both components and achieve full load/speed by using all 32 bit width of Ethernet. But the input is not only 10 bit and also running at same speed(100 MHz).
How I can map 10 bit input -> 32 bit output and at the same time maintaining full speed of Ethernet?
This will require more Ethernet bandwidth than the "full speed of Ethernet", 10 * 100 = 1000 Mbps (i.e. 1Gbps). If you are talking about a GigE connection then you'll already have a payload that exceeds the payload of Ethernet frames. You can get something like ~990Mbps sustained. If you're using a 10Gig Ethernet, then you won't be using anything close to the "full speed of Ethernet".just pad the unused bits with 0s?
Redundancy!? That makes no sense at all. 0 padding doesn't create any kind of redundancy.Then I am just wasting 32-10=22 bit width of full speed/load of Ethernet. In other word, It will be just increasing redundancy.
Any other suggestions, please.
Oh, boy more 0 fill redundancy ;-).Collect two or three inputs then write them to a 32 bit wide fifo. Fill the unused input data bits with 0.
Hi thanks for idea. I am trying to implement it in Verilog/VHDL.If that is the case the most efficient in terms of transmission is to pick a packet size with a payload that is a multiple of 10-bits and 8-bits (so the payload is a integral number of bytes) and stuff the 32-bit input with 3 10-bit words + 2 bits of the 4th word, followed by 8-bits of the 4th word + 2 words + 4-bits of the 7th word...etc.
So the ADC data will be packed with no zero fill, and the packet size will be set to the smallest size that doesn't result in exceeding the total bandwidth of the connection (including the overhead). Doing something like this will reduce you're latency for the ADC data to the minimum sustainable value.
// source interface
input System_Clock,
input System_Reset,
input [9:0] ADC_data,
output ADC_Clock
// sink interface
input System_Clock,
input System_Reset,
input asi_snk0_valid,
output asi_snk0_ready,
input [31:0] asi_snk0_data,
input [1:0] asi_snk0_empty,
input asi_snk0_startofpacket,
input asi_snk0_endofpacket
So you are driving the ADC_Clock from the FPGA and deriving it from the System_Clock? You do know that FPGAs are not that great for outputting a jitter free clock, therefore you're giving the ADC a jittery clock, which isn't great for getting good ADC output data samples.Hi thanks for idea. I am trying to implement it in Verilog/VHDL.
Could you please give some idea for mapping:
Source (Input) have following signal for 10 bit ADC:
// source interface
input System_Clock,
input System_Reset,
input [9:0] ADC_data,
output ADC_Clock
Hi,Now about the mapping...I'm assuming you're intention wasn't asking someone to write the "mapping" of the ADC interface to the Avalon streaming sink.
Hi,Wow, you must not read past posts in a thread or you just like to "hear" yourself speak. I already brought that little tidbit up back in post #5.
Hi,
I have no comment about your support for my post. It always helped me to understand the concept and its implementation better. I accepted my mistake not looking throughly on the past post before posting this question and not gonna to be repeat. I am sorry. Now I look If I found some clue I am looking for on past posts.
Wow, you must not read past posts in a thread or you just like to "hear" yourself speak. I already brought that little tidbit up back in post #5.
@beginner_EDA
Can you describe the ethernet system in more detail? You will almost certainly need to determine how things like the UDP/IP/ethernet headers get added. Usually, you have to do most of the ethernet frame header and all of the UDP/IP header. The avalon interface itself is described on page 39 of https://www.altera.com/en_US/pdfs/literature/manual/mnl_avalon_spec.pdf . The ethernet system itself should describe what start/end of packet mean in the context of the start/end of an actual ethernet frame.
input Clock,
input Reset,
input asi_snk0_valid,
output asi_snk0_ready,
input [31:0] asi_snk0_data,
input [1:0] asi_snk0_empty,
input asi_snk0_startofpacket,
input asi_snk0_endofpacket
input Clock,
input Reset,
input [9:0] ADC_data,
output ADC_Clock
adc_word = {sample[3][1:0], sample[2], sample[1], sample[0]}
next word...
adc_word = {sample[6][3:0], sample[5], sample[4], sample[3][9:2]}
module prbs_packet_generator
(
// clock interface
input csi_clock_clk,
input csi_clock_reset,
// slave interface -- 72 bits
input avs_s0_write,
input avs_s0_read,
input [1:0] avs_s0_address,
input [3:0] avs_s0_byteenable,
input [31:0] avs_s0_writedata,
output [31:0] avs_s0_readdata,
// source interface -- 38 bits
output aso_src0_valid,
input aso_src0_ready,
output [31:0] aso_src0_data,
output [1:0] aso_src0_empty,
output aso_src0_startofpacket,
output aso_src0_endofpacket,
// External input : Input from ADC
input [31:0] asi_snk0_data
);
localparam [1:0] IDLE_STATE = 2'h0;
localparam [1:0] SOP_STATE = 2'h1;
localparam [1:0] DATA_STATE = 2'h2;
localparam [1:0] EOP_STATE = 2'h3;
reg go_bit;
reg running_bit;
reg [15:0] payload_prbs_byte_count;
reg [15:0] byte_count;
reg [31:0] initial_value;
reg [31:0] next_value;
reg [31:0] packet_count;
reg clear_packet_count;
reg [1:0] state;
reg [15:0] packet_sequence_number;
wire [15:0] empty_symbols;
//
// slave read mux
//
assign avs_s0_readdata = (avs_s0_address == 2'h0) ? ({{30{1'b0}}, running_bit, go_bit}) :
(avs_s0_address == 2'h1) ? ({{16{1'b0}}, payload_prbs_byte_count}) :
(avs_s0_address == 2'h2) ? (initial_value) :
(packet_count);
//
// slave write demux
//
always @ (posedge csi_clock_clk or posedge csi_clock_reset)
begin
if(csi_clock_reset)
begin
go_bit <= 0;
payload_prbs_byte_count <= 0;
initial_value <= 0;
clear_packet_count <= 0;
end
else
begin
if(avs_s0_write)
begin
case(avs_s0_address)
2'h0:
begin
if (avs_s0_byteenable[0] == 1'b1)
go_bit <= avs_s0_writedata[0];
end
2'h1:
begin
if (avs_s0_byteenable[0] == 1'b1)
payload_prbs_byte_count[7:0] <= avs_s0_writedata[7:0];
if (avs_s0_byteenable[1] == 1'b1)
payload_prbs_byte_count[15:8] <= avs_s0_writedata[15:8];
end
2'h2:
begin
if (avs_s0_byteenable[0] == 1'b1)
initial_value[7:0] <= avs_s0_writedata[7:0];
if (avs_s0_byteenable[1] == 1'b1)
initial_value[15:8] <= avs_s0_writedata[15:8];
if (avs_s0_byteenable[2] == 1'b1)
initial_value[23:16] <= avs_s0_writedata[23:16];
if (avs_s0_byteenable[3] == 1'b1)
initial_value[31:24] <= avs_s0_writedata[31:24];
end
2'h3:
begin
clear_packet_count <= 1;
end
endcase
end
else
begin
clear_packet_count <= 0;
end
end
end
//
// packet_count state machine
//
// count the packet when we send startofpacket, the first word of the packet
//
always @ (posedge csi_clock_clk or posedge csi_clock_reset)
begin
if(csi_clock_reset)
begin
packet_count <= 0;
end
else
begin
if(clear_packet_count)
begin
packet_count <= 0;
end
else if(aso_src0_valid & aso_src0_ready & aso_src0_startofpacket)
begin
packet_count <= packet_count + 1;
end
end
end
//
// running_bit state machine
//
// we start immediately when go_bit is asserted
// we don't stop until we reach the end of the current packet that we're generating
//
always @ (posedge csi_clock_clk or posedge csi_clock_reset)
begin
if(csi_clock_reset)
begin
running_bit <= 0;
end
else
begin
if(go_bit)
begin
running_bit <= 1;
end
else if(running_bit & !go_bit & aso_src0_valid & aso_src0_ready & aso_src0_endofpacket)
begin
running_bit <= 0;
end
end
end
//
// next_value state machine
//
// this PRBS algorithm is quite simple but efficient, it takes the current
// value and rotates it 5-bits to the left and then adds the initial value to
// the rotated value.
//
always @ (posedge csi_clock_clk or posedge csi_clock_reset)
begin
if(csi_clock_reset)
begin
next_value <= 0;
end
else
begin
if(go_bit & !running_bit)
begin
next_value <= initial_value;
end
else if(((state == DATA_STATE) || (state == EOP_STATE)) && aso_src0_valid && aso_src0_ready)
begin
next_value <= asi_snk0_data; //((((next_value << 5) & 32'hFFFFFFE0) | ((next_value >> 27) & 32'h0000001F)) + 32'h33557799);
end
end
end
//
// byte_count state machine
//
// this state machine counts the number of bytes that have been transmitted in
// current packet.
//
always @ (posedge csi_clock_clk or posedge csi_clock_reset)
begin
if(csi_clock_reset)
begin
byte_count <= 0;
end
else
begin
case(state)
IDLE_STATE:
begin
byte_count <= 0;
end
SOP_STATE:
begin
byte_count <= 2;
end
DATA_STATE:
begin
if(aso_src0_valid && aso_src0_ready)
begin
byte_count <= byte_count + 4;
end
end
EOP_STATE:
begin
byte_count <= 0;
end
endcase
end
end
//
// packet_sequence_number state machine
//
// the sequence always starts at ZERO and increments once we've transmitted the
// first word of each packet.
//
always @ (posedge csi_clock_clk or posedge csi_clock_reset)
begin
if(csi_clock_reset)
begin
packet_sequence_number <= 0;
end
else
begin
if(!running_bit)
begin
packet_sequence_number <= 0;
end
else if((state == SOP_STATE) && aso_src0_valid && aso_src0_ready)
begin
packet_sequence_number <= packet_sequence_number + 1;
end
end
end
//
// source interface control
//
// these are combinatorial control equations for our source interface
//
assign empty_symbols = byte_count - payload_prbs_byte_count;
assign aso_src0_valid = running_bit;
assign aso_src0_data = (state == SOP_STATE) ? ({payload_prbs_byte_count, packet_sequence_number[7:0], packet_sequence_number[15:8]}) :
(next_value);
assign aso_src0_empty = (state == EOP_STATE) ? (empty_symbols[1:0]) :
((state == SOP_STATE) && (payload_prbs_byte_count < 1)) ? (2'h2) :
((state == SOP_STATE) && (payload_prbs_byte_count < 2)) ? (2'h1) : (2'h0);
assign aso_src0_startofpacket = (state == SOP_STATE) ? (1'b1) : (1'b0);
assign aso_src0_endofpacket = (state == EOP_STATE) ? (1'b1) :
((state == SOP_STATE) && (payload_prbs_byte_count < 3)) ? (1'b1) : (1'b0);
//
// source state machine
//
// this state machine provides synchronous sequencing for the control of the
// source interface
//
always @ (posedge csi_clock_clk or posedge csi_clock_reset)
begin
if(csi_clock_reset)
begin
state <= IDLE_STATE;
end
else
begin
case(state)
IDLE_STATE:
begin
if(go_bit)
begin
state <= SOP_STATE;
end
end
SOP_STATE:
begin
if((payload_prbs_byte_count < 3) && go_bit && aso_src0_valid && aso_src0_ready)
begin
state <= SOP_STATE;
end
else if((payload_prbs_byte_count > 6) && aso_src0_valid && aso_src0_ready)
begin
state <= DATA_STATE;
end
else if((payload_prbs_byte_count < 7) && (payload_prbs_byte_count > 2) && aso_src0_valid && aso_src0_ready)
begin
state <= EOP_STATE;
end
else if((payload_prbs_byte_count < 3) && !go_bit && aso_src0_valid && aso_src0_ready)
begin
state <= IDLE_STATE;
end
end
DATA_STATE:
begin
if(((byte_count + 8) >= payload_prbs_byte_count) && aso_src0_valid && aso_src0_ready)
begin
state <= EOP_STATE;
end
end
EOP_STATE:
begin
if(go_bit && aso_src0_valid && aso_src0_ready)
begin
state <= SOP_STATE;
end
else if(!go_bit && aso_src0_valid && aso_src0_ready)
begin
state <= IDLE_STATE;
end
end
endcase
end
end
endmodule
Hi, unfortunately I am missing the concept of implementation in verilog for collecting ADC Sample(especially clock synchronising).adc_word = {sample[3][1:0], sample[2], sample[1], sample[0]}
next word...
adc_word = {sample[6][3:0], sample[5], sample[4], sample[3][9:2]}
(note: my indices are only to show you how the incoming samples get shifted around, so don't think this is usable code)
reg [7:0] sample [2:0];
wire [7:0] adc_value;
reg trigger;
wire [31:0] 32_bit_entity;
always @ (posedge 100_mhz_clk)
begin
for (k = 0; k < 4; k = k + 1)
begin
sample[k] <= adc_value;
end
if (k == 3)
begin
trigger <= 1;
end
else
begin
trigger <= 0;
end
end
always @ (posedge 25_mhz_clk)
begin
if (trigger == 1)
begin
32_bit_entity <= sample;
end
else
begin
32_bit_entity <= 0;
end
end
Exactly and I am facing trouble with managing index and clock relationship.Presume you are intending to store one sample each 100 MHz clock and incrementing the index by one.
As ads-ee suggested above, I manage 32 bit part at 25 MHz as:The 32 bit data entity has to be synchronized between both clock domains. If not using a FIFO you'll write it to a 32 bit register in the 100 MHz domain and set a handshake flag.
wire [7:0] ADC_DATA ; // continuously coming ADC_DATA at 100 MHz Clock
reg [7:0] adc_value [0:2];
reg [31:0] 32_bit_entity;
always @ (posedge 25_mhz_clk)
begin
32_bit_entity <= {adc_value[3], adc_value[2], adc_value[1], adc_value[0]}
end
always @ (posedge 100_mhz_clk)
begin
for (k = 0; k <3; k = k +1)
begin
adc_value[k] <= ADC_DATA;
end
end
Exactly and I am facing trouble with managing index and clock relationship.
but I am sorry to say that I am not able to write into 32 bit register at 100 MHz from 8 bit continuous input and the same time maintaining synchronization between clocks. I tried in this way but I don't think it is right.
Code:always @ (posedge 100_mhz_clk) begin for (k = 0; k <3; k = k +1) begin adc_value[k] <= ADC_DATA; end end
Code Verilog - [expand] 1 2 3 4 5 6 always @ (posedge 100_mhz_clk) begin adc_value[0] <= ADC_DATA; adc_value[1] <= ADC_DATA; adc_value[2] <= ADC_DATA; adc_value[3] <= ADC_DATA; end
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 reg [1:0] idx = 0; // in Xilinx this will init the register to 2'b00, it also ensures the simulation is non-X always @ (posedge 100_mhz_clk) begin idx <= idx + 1; adc_value[idx] <= ADC_DATA; end // or as the synthesis result would be: always @ (posedge 100_mhz_clk) begin idx <= idx + 1; end always @ (posedge 100_mhz_clk) begin if (idx == 2'b00) begin adc_value[0] <= ADC_DATA; end if (idx == 2'b01) begin adc_value[1] <= ADC_DATA; end if (idx == 2'b10) begin adc_value[2] <= ADC_DATA; end if (idx == 2'b11) begin adc_value[3] <= ADC_DATA; end end
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?