Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Help needed in writing FSM for ethernet.

Status
Not open for further replies.

atif.india

Newbie level 3
Joined
Feb 19, 2008
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,317
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 .
 

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
 

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]
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top