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
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