+ Post New Thread
Results 1 to 3 of 3
  1. #1
    Newbie level 3
    Points: 879, Level: 6

    Join Date
    Feb 2008
    Posts
    3
    Helped
    0 / 0
    Points
    879
    Level
    6

    Help needed in writing FSM for ethernet.

    Hi,
    I am writing a code for Ethernet assemble where i have to first read the first loc of memory (32 bit) place the data in 8 bit temp loc (changing after every two clock cycles) then increment the mem pointer and do the same( this time it's only the fist 16 bits). I have used mod counter for the purpose. My prog looks like this

    module assembler (data,strt,eof,err2,clk,rst,buf_data,buf_addr);
    output reg [7:0] data;
    input strt,clk,rst;
    output reg eof,err2;
    input [31:0] buf_data;
    output reg [8:0] buf_addr;
    reg [31:0] frame;

    always@(buf_data)
    frame=buf_data;

    reg [3:0] mod8=4'd0;
    reg [2:0] mod4=3'd0;

    parameter idle=3'd0;
    parameter desadd=3'd1;
    parameter desadd2=3'd2;
    parameter sadd=3'd3;

    reg [2:0] state;

    always@(posedge clk)
    begin
    if (rst)
    state=idle;
    else
    case (state)
    idle: if (strt)
    state=desadd;
    else
    state=idle;

    desadd:
    if (mod8==4'd8 )
    state=desadd2;
    else
    begin
    state=desadd;
    mod8=mod8+4'd1;
    end
    desadd2:
    if (mod4==3'd4)
    state=sadd;
    else
    begin
    state=desadd2;
    mod4=mod4+3'd1;
    end

    endcase
    end

    always@(state or mod8 or mod4 or frame)
    begin
    case(state)
    idle:
    begin
    data=8'd0;
    eof=1'd0;
    err2=1'd0;
    buf_addr=9'd0;
    end
    desadd:
    begin
    case (mod8)
    4'd0: data=frame [31:24];
    4'd1: data=frame [31:24];
    4'd2: data=frame [23:16];
    4'd3: data=frame [23:16];
    4'd4: data=frame [15:8];
    4'd5: data=frame [15:8];
    4'd6: data=frame [7:0];
    4'd7: data=frame [7:0];
    default: data=8'd0;
    endcase
    end

    desadd2:
    begin
    buf_addr=9'd1;
    case(mod4)
    3'd0: data=frame [31:24];
    3'd1: data=frame [31:24];
    3'd2: data=frame [23:16];
    3'd3: data=frame [23:16];
    default: data=8'd0;
    endcase
    end

    endcase
    end
    endmodule


    When i comment out the state desadd2 and use only desadd i am getting proper output (data is taken in from buffer and is changed every two clk cycles) but the moment i add the next state my op completely disappears. What could be the prob with this case. One warning that i am getting is there is prob with inferring latches which holds its perv value in one or more path trhu always construct .

    •   AltAdvertisement

        
       

  2. #2
    Advanced Member level 3
    Points: 9,432, Level: 23

    Join Date
    Jul 2004
    Posts
    892
    Helped
    177 / 177
    Points
    9,432
    Level
    23

    Re: Help needed in writing FSM for ethernet.

    See the code below!
    Case statement for state = sadd is missing!


    Code:
    module assembler (data, strt, eof, err2, clk, rst, buf_data, buf_addr);
       output reg [7:0] data;
       input            strt, clk, rst;
       output reg       eof, err2;
       input [31:0]     buf_data;
       output reg [8:0] buf_addr;
       wire [31:0]       frame = buf_data;
       
       reg [3:0]        mod8;
       reg [2:0]        mod4;
       
       parameter idle    = 3'd0;
       parameter desadd  = 3'd1;
       parameter desadd2 = 3'd2;
       parameter sadd    = 3'd3;
       
       reg [2:0]        state;
    
       always @ (posedge clk) begin
          if (rst) begin
             state <= idle;
             mod8 <= 4'd0;
             mod4 <= 3'd0;
          end else
            case (state)
              idle: 
                if (strt)
                  state <= desadd;
                else
                  state <= idle;
              
              desadd:
                if (mod8 == 4'd8 )
                  state <= desadd2;
                else begin
                   state <= desadd;
                   mod8 <= mod8 + 4'd1;
                end
    
              desadd2:
                if (mod4 == 3'd4)
                  state <= sadd;
                else begin
                   state <= desadd2;
                   mod4 <= mod4 + 3'd1;
                end
    
              sadd : begin     // this is missing
                 
              end
            endcase // case (state)
       end // always @ (posedge clk)
       
       
       always @(state or mod8 or mod4 or frame) begin
          case (state)
            idle :  begin
               data = 8'd0;
               eof  = 1'd0;
               err2 = 1'd0;
               buf_addr = 9'd0;
            end
            
            desadd : begin
               case (mod8)
                 4'd0: data = frame[31:24];
                 4'd1: data = frame[31:24];
                 4'd2: data = frame[23:16];
                 4'd3: data = frame[23:16];
                 4'd4: data = frame[15:8];
                 4'd5: data = frame[15:8];
                 4'd6: data = frame[7:0];
                 4'd7: data = frame[7:0];
                 default: data = 8'd0;
               endcase
            end
            
            desadd2:
              begin
                 buf_addr = 9'd1;
                 case(mod4)
                   3'd0: data = frame[31:24];
                   3'd1: data = frame[31:24];
                   3'd2: data = frame[23:16];
                   3'd3: data = frame[23:16];
                   default: data = 8'd0;
                 endcase
              end
          endcase
       end // always @ (state or mod8 or mod4 or frame)
    endmodule



    •   AltAdvertisement

        
       

  3. #3
    Newbie level 3
    Points: 879, Level: 6

    Join Date
    Feb 2008
    Posts
    3
    Helped
    0 / 0
    Points
    879
    Level
    6

    Re: Help needed in writing FSM for ethernet.

    Even after adding the sadd state i am still getting 0 as op initially when i was getting op i didn't even had desadd2 state (i actually have to make entire 802.3 frame so till many more states are left for frame length, actual data) this is my new code after adding sadd

    Code:
    module assembler  (data,strt,eof,err2,clk,rst,buf_data,buf_addr);
    output reg [7:0] data;
    input strt,clk,rst;
    output reg  eof,err2;
    input [31:0] buf_data;
    output reg [8:0] buf_addr;
    reg [31:0] frame;
    
    always@(buf_data)
    	frame=buf_data;
    
    reg [3:0] mod8=4'd0;
    reg [2:0] mod4=3'd0;
    
    parameter idle=3'd0;
    parameter desadd=3'd1;
    parameter desadd2=3'd2;
    parameter sadd=3'd3;
    
    reg [2:0] state;
    
    always@(posedge clk)
    begin
    	if (rst)
    		state=idle;
    	else
    		case (state)
    	idle: if (strt)
    		state=desadd;
    		else
    		state=idle;
    	
    	desadd:
    		if (mod8==4'd8)
    			state=desadd2;
    		else
    			begin
    			state=desadd;
    			mod8=mod8+4'd1;
    			end	
    	desadd2:
    		if (mod4==3'd4)
    			state=sadd;
    		else
    			begin
    			state=desadd2;
    			mod4=mod4+3'd1;
    			end
    	sadd:
    		state=idle;
    	endcase
    end
    
    always@(state or mod8 or mod4 or frame)
    begin
    	case(state)
    idle:
    begin
    	data=8'd0;
    	eof=1'd0;
    	err2=1'd0;
    	buf_addr=9'd0;
    end	
    desadd:
    begin
    case (mod8)
    	4'd0: data=frame [31:24];
    	4'd1: data=frame [31:24];
    	4'd2: data=frame [23:16];
    	4'd3: data=frame [23:16];
    	4'd4: data=frame [15:8];
    	4'd5: data=frame [15:8];
    	4'd6: data=frame [7:0];
    	4'd7: data=frame [7:0];
    	default: data=8'd0;
    	endcase	
    end
    
    	desadd2:
    	begin
    	buf_addr=9'd1;
    	case(mod4)
    	3'd0: data=frame [31:24];
    	3'd1: data=frame [31:24];
    	3'd2: data=frame [23:16];
    	3'd3: data=frame [23:16];
    	default: data=8'd0;
       endcase
        end
    
     sadd:;
    
    endcase
    end
    endmodule
    I am attaching printscreen of of my op in both the case. This is my file for buffer

    Code:
    module buffer (datab,addr);
    input [8:0] addr;
    output reg  [31:0] datab;
    
    reg [31:0] data0=32'hfffefdfc;
    reg [31:0] data1=32'hfffefffe;
    reg [31:0] data2=32'hfffffffd;
    reg [31:0] data3=32'hfffffffc;
    reg [31:0] data4=32'hfffffffb;
    reg [31:0] data5=32'hfffffffa;
    reg [31:0] data6=32'hffffffef;
    reg [31:0] data7=32'hffffffdf;
    reg [31:0] data8=32'hffffffcf;
    reg [31:0] data9=32'hffffffbf;
    reg [31:0] data10=32'hffffffaf;
    always@(addr or data0 or data1 or data2 or data3 or data4 or data5 or data6 or data7 or data8 or data9 or data10 )
    begin
    case (addr)
     9'd0: datab=data0;
     9'd1: datab=data1;
     9'd2: datab=data2;
     9'd3: datab=data3;
     9'd4: datab=data4;
     9'd5: datab=data5;
     9'd6: datab=data6;
     9'd7: datab=data7;
     9'd8: datab=data8;
     9'd9: datab=data9;
    9'd10: datab=data10;
    default: datab=32'd0;
    endcase
    end
    endmodule
    and top level

    Code:
    module ethernet (data,strt,eof,err2,clk,rst);
    input clk,rst,strt;
    output eof,err2;
    output [7:0] data;
    wire [31:0] buf_data;
    wire [8:0] buf_addr;
    buffer b1 (buf_data,buf_addr);
    assembler b2 (data,strt,eof,err2,clk,rst,buf_data,buf_addr);
    endmodule
    [/code]



--[[ ]]--