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
Hi,ASCII character 8-bit wide by N entry shift register, a loadable string register, a big mask comparator to match the loaded string with the input string.
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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 input [3:0] ENET0_RX_DATA; output [3:0] payload; reg [3:0] input_data [0:23]; reg [4:0] index = 0; reg [95:0] string_check = 0; reg trigger_for_payload = 0; always @ (posedge test_250_mhz) begin index <= index + 1; if (index > 23) begin index <= 0; end input_data[index] <= ENET0_RX_DATA; end always @ (posedge test_250_mhz) begin if (index == 0) begin string_check <= {input_data[0], input_data[1], input_data[2], input_data[3], input_data[4], input_data[5], input_data[6], input_data[7], input_data[8], input_data[9], input_data[10], input_data[11], input_data[12], input_data[13], input_data[14], input_data[15], input_data[16], input_data[17], input_data[18], input_data[19], input_data[20], input_data[21], input_data[22], input_data[23]}; end if (string_check == 0xe0db44d6855f0007edfe8f10) // 96 bit known source and //destination address begin trigger_for_payload <= 1; end end end always @ (posedge test_250_mhz) begin if (trigger_for_payload == 1) begin payload <= ENET0_RX_DATA end end
The problem you are having looks to be with how to pipeline a design.but I couldn't understand how to rotate/shift at the same time while comparing the string?
Hi this seems to be very complicated.The problem you are having looks to be with how to pipeline a design.
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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 // string to check from 4 bit continuous input: 0xe0db44d6855f0007edfe8f10 // once this string(MAC Address of SRC and DST) identified, start payload. localparam [4:0] IDLE = 5'd0; localparam [4:0] STATE_0 = 5'd1; localparam [4:0] STATE_1 = 5'd2; localparam [4:0] STATE_2 = 5'd3; localparam [4:0] STATE_3 = 5'd4; localparam [4:0] STATE_4 = 5'd5; localparam [4:0] STATE_5 = 5'd6; localparam [4:0] STATE_6 = 5'd7; localparam [4:0] STATE_7 = 5'd8; localparam [4:0] STATE_8 = 5'd9; localparam [4:0] STATE_9 = 5'd10; localparam [4:0] STATE_10 = 5'd11; localparam [4:0] STATE_11 = 5'd12; localparam [4:0] STATE_12 = 5'd13; localparam [4:0] STATE_13 = 5'd14; localparam [4:0] STATE_14 = 5'd15; localparam [4:0] STATE_15 = 5'd16; localparam [4:0] STATE_16 = 5'd17; localparam [4:0] STATE_17 = 5'd18; localparam [4:0] STATE_18 = 5'd19; localparam [4:0] STATE_19 = 5'd20; localparam [4:0] STATE_20 = 5'd21; localparam [4:0] STATE_21 = 5'd22; localparam [4:0] STATE_22 = 5'd23; input [3:0] ENET0_RX_DATA; output [3:0] payload; reg [4:0] state; reg trigger_for_payload; always @ (posedge test_250_mhz or posedge clock_reset) begin if(clock_reset) begin state <= IDLE; end else begin case(state) IDLE: begin if(ENET0_RX_DATA == 0xe) begin state <= STATE_0; end else begin state <= IDLE; end end STATE_0: begin if(ENET0_RX_DATA == 0x0) begin state <= STATE_1; end else begin state <= IDLE; end end STATE_1: begin if(ENET0_RX_DATA == 0xd) begin state <= STATE_2; end else begin state <= IDLE; end end STATE_2: begin if(ENET0_RX_DATA == 0xb) begin state <= STATE_3; end else begin state <= IDLE; end end STATE_3: begin if(ENET0_RX_DATA == 0x4) begin state <= STATE_4; end else begin state <= IDLE; end end STATE_4: begin if(ENET0_RX_DATA == 0x4) begin state <= STATE_5; end else begin state <= IDLE; end end STATE_5: begin if(ENET0_RX_DATA == 0xd) begin state <= STATE_6; end else begin state <= IDLE; end end STATE_6: begin if(ENET0_RX_DATA == 0x6) begin state <= STATE_7; end else begin state <= IDLE; end end STATE_7: begin if(ENET0_RX_DATA == 0x8) begin state <= STATE_8; end else begin state <= IDLE; end end STATE_8: begin if(ENET0_RX_DATA == 0x5) begin state <= STATE_9; end else begin state <= IDLE; end end STATE_9: begin if(ENET0_RX_DATA == 0x5) begin state <= STATE_10; end else begin state <= IDLE; end end STATE_10: begin if(ENET0_RX_DATA == 0xf) begin state <= STATE_11; end else begin state <= IDLE; end end STATE_11: begin if(ENET0_RX_DATA == 0x0) begin state <= STATE_12; end else begin state <= IDLE; end end STATE_12: begin if(ENET0_RX_DATA == 0x0) begin state <= STATE_13; end else begin state <= IDLE; end end STATE_PW_13: begin if(ENET0_RX_DATA == 0x0) begin state <= STATE_14; end else begin state <= IDLE; end end STATE_14: begin if(ENET0_RX_DATA == 0x7) begin state <= STATE_15; end else begin state <= IDLE; end end STATE_15: begin if(ENET0_RX_DATA == 0xe) begin state <= STATE_16; end else begin state <= IDLE; end end STATE_16: begin if(ENET0_RX_DATA == 0xd) begin state <= STATE_17; end else begin state <= IDLE; end end STATE_17: begin if(ENET0_RX_DATA == 0xf) begin state <= STATE_18; end else begin state <= IDLE; end end STATE_18: begin if(ENET0_RX_DATA == 0xe) begin state <= STATE_19; end else begin state <= IDLE; end end STATE_19: begin if(ENET0_RX_DATA == 0x8) begin state <= STATE_20; end else begin state <= IDLE; end end STATE_20: begin if(ENET0_RX_DATA == 0xf) begin state <= STATE_21; end else begin state <= IDLE; end end STATE_21: begin if(ENET0_RX_DATA == 0x1) begin state <= STATE_22; end else begin state <= IDLE; end end STATE_22: begin if(ENET0_RX_DATA == 0x0) begin trigger_for_payload <= 1; end end default: begin state <= IDLE; end endcase end end always @ (posedge test_250_mhz) begin if (trigger_for_payload == 1) begin payload <= ENET0_RX_DATA end end
Hi FvM,It's said that the "continuous data stream" is ethernet data. So packet respectively frame synchronization takes place before the MAC fields. Any state/index counter has to refer to it.
Hi this seems to be very complicated.
Can I use state machine for this purpose?
HiYou are using an index to demultiplex, when you should just use a shift register. Then you had registers holding values for string_check, trigger_for_payload, and payload, but none of them are fed from pipeline registers to align what they are each doing.
Hi
sorry but I am not able to formulate code for shift register in this case.
could you please provide some hints.
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 [7:0] my_array [0:31]; // 32-element array of bytes always @ (posedge clk) begin // shift register code for (i=0;i<32;i=i+1) begin if (i==0) begin my_array[i] <= input_byte; end else begin my_array[i] <= my_array[i-1]; end end end // the above is the equivalent of...(with loop unrolled) always @(posedge clk) begin my_array[0] <= input_byte; my_array[1] <= my_array[0]; //... my_array[31] <= my_array[30]; end // another cumbersome method... always @ (posedge clk) begin // note ... means there are a lot of my_array[*] in between, that I'm too lazy to write out {my_array[31], my_array[30], .... , my_array[1], my_array[0]} <= {my_array[30], ... , my_array[0], input_byte}; end
Thanks for the code.Here is an example of a byte shift register that can shift 32 bytes
Code Verilog - [expand] 1 2 3 4 5 6 7 8 always @ (posedge clock) begin if (my_array == my_string) begin trigger_for_payload <= 1; end end
I am not sure if I can check my string (0xe0db44d6855f0007edfe8f10 // 96 bit known source and destination address)
like below and set trigger:
Code Verilog - [expand] 1 2 3 4 5 6 7 8 always @ (posedge clock) begin if (my_array == my_string) begin trigger_for_payload <= 1; end end
and reset of index 0,1, ...31 is not needed?
Note: Here my_array mean {my_array[0], my_array[1], ...my_array[31]} and assuming my_string is of same size of my_array.
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 localparam data_width = 8; localparam shift_leng = 32; reg [data_width*shift_leng-1:0] shift_reg; // most significant byte is in the highest bits (i.e. the first value // that was shifted in). always @ (posedge clk) begin shift_reg[data_width-1:0] <= input_data[data_width-1:0]; for (i=1;i<shift_leng;i=i+1) begin shift_reg[data_width*i +:data_width] <= shift_reg[data_width*(i-1) +:data_width]; end end // then the comparison is simply if (shift_reg == 256'h1234_1234_1234_1234_1234_1234_1234_1234) begin // code that does something when shift_reg content matches. end
Code Verilog - [expand] 1 {my_array[31], my_array[30]....my_array[1],my_array[0]} == 256'h1234_1234_1234_1234_1234_1234_1234_1234
Try modular appoach, first make a FIFO register of the length of bytes u need to compare, on every byte updation compare the FIFO register with required bytes, FSM is an efficient and systematic way of doing it, u should give it a try, I did the same kind of thing with UART, FIFO register worked for me
your satates may b, if(header_match) nstate
if(msb_match) n state etc
Hi,
I tried FSM as mentioned in post #5 of this thread but unfortunately I didn't get expected result.
Could you please post the major part of code.
Hi, Thanks. String checking is working using this pipeline method.Drats, I forgot about you wanting to compare that string of yours to a 96-bit value.
Then you should perform the shift as follows using the same example shift register of bytes with 32 deep shift register.
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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 // payload starts after 42 byte header. Frame = 14 byte, IP = 20 byte, UDP = 8 byte. // and I am checking just first 12 byte of Frame header which is combination of source(6 byte) and destination(6 byte) //MAC Address. This means my payload must start after 30 byte once string is checked. // For Frame synchronization, I am extracting UDP Length field and assigning to a counter as: // counter <= UDP Length field - 8; // and decrementing counter and once counter is zero start new Frame (string check) reg trigger = 0; reg [95:0] string_check = 0; reg [3:0] payload; reg [3:0] extract_length [51:54]; reg trigger_reset = 0; reg [15:0] count = 0; reg [7:0] ct_extract_leng = 0; reg [7:0] count_sec = 0; localparam data_width = 4; localparam shift_leng = 24; reg [4:0] i = 0; reg [data_width*shift_leng-1:0] shift_reg; // most significant byte is in the highest bits (i.e. the first value // that was shifted in). always @ (posedge test_250_mhz) begin shift_reg[data_width-1:0] <= ENET0_RX_DATA; for (i=1;i<shift_leng;i=i+1) begin shift_reg[data_width*i +:data_width] <= shift_reg[data_width*(i-1) +:data_width]; end end // then the comparison is simply if (shift_reg == 96'h0070DEFFF8010EBD556DF8F5) // code that does something when shift_reg content matches. begin trigger <= 1; end if (trigger_reset == 1) begin trigger <= 0; end end // to extract payload length from UDP length field. UDP Payload length field is 26 byte after string check is done. // i.e. 52 nibble. but there is one register delay. So, I took 51, 52, 53, 54 nibble. always @ (posedge test_250_mhz) begin if (trigger == 1) begin ct_extract_leng <= ct_extract_leng + 1; if ((ct_extract_leng > 50) && (ct_extract_leng < 55)) begin extract_length [ct_extract_leng] <= ENET0_RX_DATA; end if (ct_extract_leng > 54) begin ct_extract_leng <= 0; end end end // resetting the Frame for Frame synchronization always @ (posedge test_250_mhz) begin count <= {extract_length[51], extract_length[52], extract_length[53], extract_length[54]} - 8 ; count <= count - 1 ; if (count == 0) begin trigger_reset <= 1; end else begin trigger_reset <= 0; end end // Taking the payload data always @ (posedge test_250_mhz) begin if (trigger == 1) begin count_sec <= count_sec + 1; if (count_sec > 60) begin Rx_fifo_write <= 1; payload <= ENET0_RX_DATA; end else begin Rx_fifo_write <= 0; count_sec <= 0; end end end
if ((ct_extract_leng > 50) && (ct_extract_leng < 55)) begin
extract_length [ct_extract_leng] <= ENET0_RX_DATA;
end
extract_length[51] <= (ct_extract_leng == 51) ? ENET0_RX_DATA : extract_length[51];
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?