I have written a state machine in Verilog. However, when I try to simulate it with my testbench, it does not advance from the STATUS_IDLE state to the STATUS_READY state. Why isn't the state machine advancing as I would expect?
This is my testbench:
`timescale 1 ns / 1 ps
module test_test;
wire gpio1, gpio2, gpio3, E_TXEN, E_RESET;
wire[3:0] E_TXD;
wire[3:0] led;
reg clk, rst_n, E_RXC, E_TXC;
reg[3:0] key;
test test (
clk,
rst_n,
E_RXC,
E_RESET,
E_TXEN,
E_TXD,
key,
led,
gpio1,
gpio2,
gpio3
);
// The following code initializes the Global Set Reset (GSR) and Global Three-State (GTS) nets
// Refer to the Synthesis and Simulation Design Guide for more information on this process
// reg GSR;
// assign glbl.GSR = GSR;
// reg GTS;
// assign glbl.GTS = GTS;
initial begin
clk <= 0;
E_TXC <= 0;
E_RXC <= 0;
key <= 4'b0000;
rst_n <= 1'b0;
#100;
key <= 4'b1111;
rst_n <= 1'b1;
// GSR = 1;
// GTS = 0; // GTS is not activated by default
// #100; // GSR is set for 100 ns
// GSR = 0;
end
// forever begin
// end
always #20 clk = ~clk;
always #40 E_TXC = ~E_TXC;
always #40 E_RXC = ~E_RXC;
// Initialize Inputs
// `define auto_init
//
// `ifdef auto_init
//
// initial begin
// end
//
// `endif
endmodule
This is my code:
module test(
input clk,
input rst_n,
input E_RXC,
// output E_RXER,
//output[3:0] E_RXD,
input E_TXC,
output E_RESET,
output wire E_TXEN,
output reg[3:0] E_TXD,
input wire[3:0] key,
output wire[3:0] led,
output gpio1,
output gpio2,
output gpio3
);
// udp
parameter UDP_SRC_PORT = 16'd8080; // LE
parameter UDP_DST_PORT = 16'd8080;
parameter _UDP_DATA_LENGTH_UNIT = 16'd14;
parameter UDP_HEADER_AND_DATA_LENGTH = 16'd8 + _UDP_DATA_LENGTH_UNIT;
parameter UDP_CRC = 16'd0;
// 64bits = 8bytes
parameter UDP_DATA = 112'b1;
// 112bits = 14bytes
// 176bits = 22bytes
// ip
parameter IP_VERSION = 4'd4; // IPV4
parameter IP_HEADER_LENGTH = 4'd5; // header's lenght(1/4bytes)
parameter IP_SERVER_TYPE = 8'h0; //
parameter IP_HEADER_AND_DATA_LENGTH = 16'd0 + UDP_HEADER_AND_DATA_LENGTH + IP_HEADER_LENGTH * 4; // udp length + ip header's lenght
parameter IP_ID = 16'h0; // ID
parameter IP_GROUP_FLAG = 3'b010; // is GROUP? this is no
parameter IP_GROUP_B_SHIFT = 13'd0; // dont group
parameter IP_TTL = 8'h80; // TTL
parameter IP_TRANSPORT_LAYER_PROTOCOL = 8'h11; // UDP
parameter IP_CRC = 16'h0; // CRC
parameter IP_SRC_ADDRESS = {8'd192, 8'd168, 8'd106, 8'd2};
parameter IP_DST_ADDRESS = {8'd192, 8'd168, 8'd106, 8'd1};
parameter IP_OPTIOPN = 0;
// 160bits = 20bytes
// mac
parameter MAC_PRE = 64'hd5_55_55_55_55_55_55_55; // pre code, required
//parameter _MAC_DST = 48'h00_0e_c6_dc_b4_a4;
parameter _MAC_DST = 48'hff_ff_ff_ff_ff_ff; // boardcast
parameter MAC_DST_ORDERED = ((_MAC_DST<<4 & 48'hf0_f0_f0_f0_f0_f0)|(_MAC_DST>>4 & 48'h0f_0f_0f_0f_0f_0f));
parameter _MAC_SRC = 48'h11_11_11_11_11_11;
parameter MAC_SRC_ORDERED = ((_MAC_SRC<<4 & 48'hf0_f0_f0_f0_f0_f0)|(_MAC_SRC>>4 & 48'h0f_0f_0f_0f_0f_0f));
parameter MAC_TYPE = 16'h0800; // mac frame type: ip
// 176bits = 22bytes
// status
parameter STATUS_IDLE = 4'd0;
parameter STATUS_READY = 4'd1;
parameter STATUS_SEND_PRE = 4'd2;
parameter STATUS_SEND_MAC = 4'd3;// en crc
parameter STATUS_SEND_IP = 4'd4;
parameter STATUS_SEND_UDP = 4'd5;
parameter STATUS_SEND_CRC = 4'd6;
//parameter STATUS_SEND_IP = 4'd4;
//parameter STATUS_SEND_UDP = 4'd5;
assign gpio1 = E_TXC;
assign gpio2 = E_RXC;
assign gpio3 = 1;
assign E_RESET = ~key[0];
assign E_TXEN = 0;
wire[7:0] data_in;
reg crc_rst, crc_en;
wire[31:0] crc_next;
wire[31:0] crc_out;
crc crc(E_TXC, crc_rst, data_in, crc_en, crc_out, crc_next);
assign data_in = {4'b0, E_TXD};
reg[3:0] status;
assign led = status;
reg[7:0] i, j;
reg[7:0] crc_reg;
reg[15:0] pre[3:0];
reg[15:0] mac[6:0];
reg[15:0] ip[9:0];
reg[15:0] udp[3:0];
reg[31:0] time_counter;
always @(negedge E_TXC or negedge rst_n)
begin
//led <= status;
if (!rst_n) begin
status <= STATUS_IDLE;
time_counter <= 0;
// led <= 4'b1111;
end
else begin
case (status)
STATUS_IDLE : begin
//led <= 4'b1110;
//E_TXEN <= 1;
crc_en <= 0;
crc_rst <= 1;
//E_TXC <= 1'bz;
i <= 0;
if (time_counter == 32'd500) begin
status <= STATUS_READY;
time_counter <= 32'd0;
end
else begin
time_counter <= time_counter + 32'd1;
end
end
STATUS_READY : begin
//led <= 4'b1100;
pre[0] <= MAC_PRE[63:48];
pre[1] <= MAC_PRE[47:32];
pre[2] <= MAC_PRE[31:16];
pre[3] <= MAC_PRE[15:0];
mac[0] <= MAC_DST_ORDERED[47:32];
mac[1] <= MAC_DST_ORDERED[31:16];
mac[2] <= MAC_DST_ORDERED[15:0];
mac[3] <= MAC_SRC_ORDERED[47:32];
mac[4] <= MAC_SRC_ORDERED[31:16];
mac[5] <= MAC_SRC_ORDERED[15:0];
mac[6] <= MAC_TYPE;
ip[0] <= {IP_VERSION, IP_HEADER_LENGTH, IP_SERVER_TYPE};
ip[1] <= {IP_HEADER_AND_DATA_LENGTH};
ip[2] <= {IP_ID};
ip[3] <= {IP_GROUP_FLAG, IP_GROUP_B_SHIFT};
ip[4] <= {IP_TTL, IP_TRANSPORT_LAYER_PROTOCOL};
ip[5] <= {IP_CRC};
ip[6] <= IP_SRC_ADDRESS[31:16];
ip[7] <= IP_SRC_ADDRESS[15:0];
ip[8] <= IP_DST_ADDRESS[31:16];
ip[9] <= IP_DST_ADDRESS[15:0];
//ip[6] <= {8'd192, 8'd168};
//ip[7] <= {8'd106, 8'd2};
//ip[8] <= {8'd192, 8'd168};
//ip[9] <= {8'd106, 8'd1};
udp[0] <= UDP_SRC_PORT;
udp[1] <= UDP_DST_PORT;
udp[2] <= UDP_HEADER_AND_DATA_LENGTH;
udp[3] <= UDP_CRC;
status <= STATUS_SEND_PRE;
end
STATUS_SEND_PRE : begin
//led <= 4'b1000;
if (i < 4) begin
j <= j + 8'd1;
case (j)
8'd0 : E_TXD <= pre[i][15:12];
8'd1 : E_TXD <= pre[i][11:8];
8'd2 : E_TXD <= pre[i][7:4];
8'd3 : begin
E_TXD <= pre[i][3:0];
j <= 0;
i <= i + 8'b1;
end
endcase
end
else begin
status <= STATUS_SEND_MAC;
i <= 0;
end
end
STATUS_SEND_MAC : begin
//led <= 4'b0010;
crc_en <= 1;
crc_rst <= 0;
if (i < 7) begin
j <= j + 8'd1;
case (j)
8'd0 : E_TXD <= mac[i][15:12];
8'd1 : E_TXD <= mac[i][11:8];
8'd2 : E_TXD <= mac[i][7:4];
8'd3 : begin
E_TXD <= mac[i][3:0];
j <= 0;
i <= i + 8'b1;
end
endcase
end
else begin
status <= STATUS_SEND_IP;
i <= 0;
end
end
STATUS_SEND_IP : begin
//led <= 4'b0001;
if (i < 10) begin
j <= j + 8'd1;
case (j)
8'd0 : E_TXD <= ip[i][15:12];
8'd1 : E_TXD <= ip[i][11:8];
8'd2 : E_TXD <= ip[i][7:4];
8'd3 : begin
E_TXD <= ip[i][3:0];
j <= 0;
i <= i + 8'b1;
end
endcase
end
else begin
status <= STATUS_SEND_UDP;
i <= 0;
end
end
STATUS_SEND_UDP : begin
if (i < 4) begin
j <= j + 8'd1;
case (j)
8'd0 : E_TXD <= udp[i][15:12];
8'd1 : E_TXD <= udp[i][11:8];
8'd2 : E_TXD <= udp[i][7:4];
8'd3 : begin
E_TXD <= udp[i][3:0];
j <= 0;
i <= i + 8'b1;
end
endcase
end
else begin
status <= STATUS_SEND_CRC;
i <= 0;
end
end
STATUS_SEND_CRC : begin
j <= j + 8'd1;
case (j)
8'd0 : E_TXD <= {~crc_out[28], ~crc_out[29], ~crc_out[30], ~crc_out[31]};
8'd1 : E_TXD <= {~crc_out[24], ~crc_out[25], ~crc_out[26], ~crc_out[27]};
8'd2 : E_TXD <= {~crc_out[20], ~crc_out[21], ~crc_out[22], ~crc_out[23]};
8'd3 : E_TXD <= {~crc_out[16], ~crc_out[17], ~crc_out[18], ~crc_out[19]};
8'd4 : E_TXD <= {~crc_out[12], ~crc_out[13], ~crc_out[14], ~crc_out[15]};
8'd5 : E_TXD <= {~crc_out[8], ~crc_out[9], ~crc_out[10], ~crc_out[11]};
8'd6 : E_TXD <= {~crc_out[4], ~crc_out[5], ~crc_out[6], ~crc_out[7]};
8'd7 : begin
E_TXD <= {~crc_out[0], ~crc_out[1], ~crc_out[2], ~crc_out[3]};
j <= 0;
status <= STATUS_IDLE;
end
endcase
end
endcase
end
end
endmodule
`timescale 1ns / 1ps
module crc (clk, reset, data_in, en, crc_out, crc_next);
parameter Tp = 1;
input clk;
input reset;
input [7:0] data_in;
input en;
output [31:0] crc_out;
reg [31:0] crc_out;
output [31:0] crc_next;
wire [7:0] data;
assign data={data_in[0],data_in[1],data_in[2],data_in[3],data_in[4],data_in[5],data_in[6],data_in[7]};
assign crc_next[0] = crc_out[24] ^ crc_out[30] ^ data[0] ^ data[6];
assign crc_next[1] = crc_out[24] ^ crc_out[25] ^ crc_out[30] ^ crc_out[31] ^ data[0] ^ data[1] ^ data[6] ^ data[7];
assign crc_next[2] = crc_out[24] ^ crc_out[25] ^ crc_out[26] ^ crc_out[30] ^ crc_out[31] ^ data[0] ^ data[1] ^ data[2] ^ data[6] ^ data[7];
assign crc_next[3] = crc_out[25] ^ crc_out[26] ^ crc_out[27] ^ crc_out[31] ^ data[1] ^ data[2] ^ data[3] ^ data[7];
assign crc_next[4] = crc_out[24] ^ crc_out[26] ^ crc_out[27] ^ crc_out[28] ^ crc_out[30] ^ data[0] ^ data[2] ^ data[3] ^ data[4] ^ data[6];
assign crc_next[5] = crc_out[24] ^ crc_out[25] ^ crc_out[27] ^ crc_out[28] ^ crc_out[29] ^ crc_out[30] ^ crc_out[31] ^ data[0] ^ data[1] ^ data[3] ^ data[4] ^ data[5] ^ data[6] ^ data[7];
assign crc_next[6] = crc_out[25] ^ crc_out[26] ^ crc_out[28] ^ crc_out[29] ^ crc_out[30] ^ crc_out[31] ^ data[1] ^ data[2] ^ data[4] ^ data[5] ^ data[6] ^ data[7];
assign crc_next[7] = crc_out[24] ^ crc_out[26] ^ crc_out[27] ^ crc_out[29] ^ crc_out[31] ^ data[0] ^ data[2] ^ data[3] ^ data[5] ^ data[7];
assign crc_next[8] = crc_out[0] ^ crc_out[24] ^ crc_out[25] ^ crc_out[27] ^ crc_out[28] ^ data[0] ^ data[1] ^ data[3] ^ data[4];
assign crc_next[9] = crc_out[1] ^ crc_out[25] ^ crc_out[26] ^ crc_out[28] ^ crc_out[29] ^ data[1] ^ data[2] ^ data[4] ^ data[5];
assign crc_next[10] = crc_out[2] ^ crc_out[24] ^ crc_out[26] ^ crc_out[27] ^ crc_out[29] ^ data[0] ^ data[2] ^ data[3] ^ data[5];
assign crc_next[11] = crc_out[3] ^ crc_out[24] ^ crc_out[25] ^ crc_out[27] ^ crc_out[28] ^ data[0] ^ data[1] ^ data[3] ^ data[4];
assign crc_next[12] = crc_out[4] ^ crc_out[24] ^ crc_out[25] ^ crc_out[26] ^ crc_out[28] ^ crc_out[29] ^ crc_out[30] ^ data[0] ^ data[1] ^ data[2] ^ data[4] ^ data[5] ^ data[6];
assign crc_next[13] = crc_out[5] ^ crc_out[25] ^ crc_out[26] ^ crc_out[27] ^ crc_out[29] ^ crc_out[30] ^ crc_out[31] ^ data[1] ^ data[2] ^ data[3] ^ data[5] ^ data[6] ^ data[7];
assign crc_next[14] = crc_out[6] ^ crc_out[26] ^ crc_out[27] ^ crc_out[28] ^ crc_out[30] ^ crc_out[31] ^ data[2] ^ data[3] ^ data[4] ^ data[6] ^ data[7];
assign crc_next[15] = crc_out[7] ^ crc_out[27] ^ crc_out[28] ^ crc_out[29] ^ crc_out[31] ^ data[3] ^ data[4] ^ data[5] ^ data[7];
assign crc_next[16] = crc_out[8] ^ crc_out[24] ^ crc_out[28] ^ crc_out[29] ^ data[0] ^ data[4] ^ data[5];
assign crc_next[17] = crc_out[9] ^ crc_out[25] ^ crc_out[29] ^ crc_out[30] ^ data[1] ^ data[5] ^ data[6];
assign crc_next[18] = crc_out[10] ^ crc_out[26] ^ crc_out[30] ^ crc_out[31] ^ data[2] ^ data[6] ^ data[7];
assign crc_next[19] = crc_out[11] ^ crc_out[27] ^ crc_out[31] ^ data[3] ^ data[7];
assign crc_next[20] = crc_out[12] ^ crc_out[28] ^ data[4];
assign crc_next[21] = crc_out[13] ^ crc_out[29] ^ data[5];
assign crc_next[22] = crc_out[14] ^ crc_out[24] ^ data[0];
assign crc_next[23] = crc_out[15] ^ crc_out[24] ^ crc_out[25] ^ crc_out[30] ^ data[0] ^ data[1] ^ data[6];
assign crc_next[24] = crc_out[16] ^ crc_out[25] ^ crc_out[26] ^ crc_out[31] ^ data[1] ^ data[2] ^ data[7];
assign crc_next[25] = crc_out[17] ^ crc_out[26] ^ crc_out[27] ^ data[2] ^ data[3];
assign crc_next[26] = crc_out[18] ^ crc_out[24] ^ crc_out[27] ^ crc_out[28] ^ crc_out[30] ^ data[0] ^ data[3] ^ data[4] ^ data[6];
assign crc_next[27] = crc_out[19] ^ crc_out[25] ^ crc_out[28] ^ crc_out[29] ^ crc_out[31] ^ data[1] ^ data[4] ^ data[5] ^ data[7];
assign crc_next[28] = crc_out[20] ^ crc_out[26] ^ crc_out[29] ^ crc_out[30] ^ data[2] ^ data[5] ^ data[6];
assign crc_next[29] = crc_out[21] ^ crc_out[27] ^ crc_out[30] ^ crc_out[31] ^ data[3] ^ data[6] ^ data[7];
assign crc_next[30] = crc_out[22] ^ crc_out[28] ^ crc_out[31] ^ data[4] ^ data[7];
assign crc_next[31] = crc_out[23] ^ crc_out[29] ^ data[5];
always @ (posedge clk, posedge reset)
begin
if (reset) begin
crc_out <={32{1'b1}};
end
else if (en)
crc_out <=crc_next;
end
endmodule