Help with Verilog Code

S

Sink0

Guest
Hi, i have a very weird behavior on a Veriglog code and i need some help.

Just a fast exaplanation. It is a Wishbone master that should perform
reads, and the number N is defined by a number that i load on th
r_counter.

The code is the following:

`include "network_controller_constants.v"

module NETWORK_CONTROLLER_WB_MASTER
(
CLK_I,
RST_I,

MINT_O,
MADR_O,
MDAT_O,
MDAT_I,
MSEL_O,
MCYC_O,
MSTB_O,
MWE_O,
MCAB_O,
MACK_I,
MRTY_I,
MERR_I,

tx_b1_offset,
tx_b2_offset,
rx_b1_offset,
rx_b2_offset,

r_cnt_reg,
r_cmnd_flag,

tx_b_1_int,
tx_b_2_int,
rx_b_1_int,
rx_b_2_int,

tx_b_1_over,
tx_b_2_over,
rx_b_1_over,
rx_b_2_over,

r_counter_empty,
counter_loaded,

r_bus_data_in,
data_sent,
DATA_READY,

leds,

MEMORY
);


input CLK_I;
input RST_I;

output MINT_O;
output [31:0] MADR_O;
input [31:0] MDAT_I;
output [31:0] MDAT_O;
output [3:0] MSEL_O;
output MCYC_O;
output MSTB_O;
output MWE_O;
output MCAB_O;
input MACK_I;
input MRTY_I;
input MERR_I;

input [31:0] tx_b1_offset;
input [31:0] tx_b2_offset;
input [31:0] rx_b1_offset;
input [31:0] rx_b2_offset;

output tx_b_1_over;
output tx_b_2_over;
output rx_b_1_over;
output rx_b_2_over;

input [31:0] r_cnt_reg;
input r_cmnd_flag;

input tx_b_1_int;
input tx_b_2_int;
input rx_b_1_int;
input rx_b_2_int;

output r_counter_empty;

output [31:0] MEMORY;

input [31:0] r_bus_data_in;
output data_sent;
input DATA_READY;

output [3:0] leds;

output counter_loaded;

parameter WB_IDLE = 5'b00001;
parameter WB_WRITING = 5'b00010;
parameter WB_READING = 5'b00100;
parameter WB_INT_ACK = 5'b01000;
parameter WB_W_WAIT = 5'b10000;

reg [31:0] MADR_O = 32'h40000000;
reg [31:0] MDAT_O;
wire [31:0] MDAT_I;
wire [3:0] MSEL_O;
reg MCYC_O;
reg MSTB_O;
wire MWE_O;
reg MCAB_O;
wire MACK_I;
wire MRTY_I;
wire MINT_O;

reg [31:0] r_counter = 0;
reg [4:0] state_machine = WB_IDLE;
reg [4:0] next_state = WB_IDLE;
reg int_ack_done = 0;
reg write_done = 0;
reg r_counter_empty = 1'b1;
wire wb_int_gen;
wire DATA_READY;

reg tx_b_1_over = 0;
reg tx_b_2_over = 0;
reg rx_b_1_over = 0;
reg rx_b_2_over = 0;

reg [31:0] MEMORY;
wire [31:0] r_bus_data_in;
reg data_sent = 0;

reg [29:0] r_w_addr;

//###########################################################

reg [3:0] MRTY_C = 0;
reg [3:0] MACK_C = 0;
reg [3:0] leds;

//###########################################################

assign MSEL_O = 4'b1111;
assign MINT_O = wb_int_gen;
//assign DATA_READY = 1'b0;

assign wb_int_gen = tx_b_1_int|
tx_b_2_int|
rx_b_1_int|
rx_b_2_int;

/*##################################################################################
############################ state_machine CONTRO
#################################
##################################################################################*/

always@(state_machine or r_counter or tx_b_1_int or tx_b_2_int o
write_done or int_ack_done or DATA_READY)
begin
tx_b_1_over = 1'b0;
tx_b_2_over = 1'b0;
rx_b_1_over = 1'b0;
rx_b_2_over = 1'b0;
case (state_machine)
WB_IDLE :
begin
if(r_counter > 32'h00000000)
begin
next_state = WB_READING;
end
end
WB_READING :
begin
if(r_counter == 32'h00000000)
begin
//next_state = WB_INT_ACK;
next_state = WB_IDLE;
rx_b_1_over = 1'b1;
end
end
WB_WRITING :
begin
if(DATA_READY == 1'b0)
next_state = WB_W_WAIT;
end
WB_INT_ACK :
begin
if(int_ack_done)
next_state = WB_IDLE;
end
WB_W_WAIT :
begin
if(write_done)
begin
next_state = WB_INT_ACK;
tx_b_1_over = 1'b1;
end
end
default:begin
next_state = WB_IDLE ;
end
endcase
end

/*##################################################################################
############################ state_machine TIMING
##################################
##################################################################################*/

always@(posedge CLK_I)
begin
state_machine = next_state;
end

/*##################################################################################
############################ int_ack_done CONTROL
##################################
##################################################################################*/

always@(posedge CLK_I)
begin
int_ack_done = 1'b0;
if(state_machine == WB_INT_ACK)
begin
if(MCYC_O && MACK_I)
int_ack_done = 1'b1;
end
end

/*##################################################################################
############################# write_done CONTROL
###################################
##################################################################################*/

always@(posedge CLK_I)
begin
write_done = 1'b0;
if(state_machine == WB_W_WAIT)
begin
if(MCYC_O && MACK_I)
write_done = 1'b1;
end
end

always@(posedge CLK_I)
begin
case (next_state)
WB_IDLE : begin
if(r_cmnd_flag)
begin
r_counter <= r_cnt_reg;
r_w_addr <= 30'h0;
end
end
WB_READING : begin
if(MCYC_O && MACK_I)
begin
if(r_counter > 0)
begin
r_counter <= r_counter - 32'h1;
r_w_addr <= r_w_addr + 30'h4;
end
end
end
WB_WRITING : begin
if(MCYC_O && MACK_I)
begin
r_w_addr <= r_w_addr + 29'h4;
data_sent = ~data_sent;
end
end
endcase
// end
end

always@(negedge CLK_I)
begin
case(next_state)
WB_IDLE: begin
MADR_O[30:0] <= r_w_addr + tx_b1_offset[30:0];
MADR_O[31] <= 1'b0;
MCAB_O <= 1;
end
WB_READING: begin
MADR_O[30:0] <= r_w_addr + tx_b1_offset[30:0];
MADR_O[31] <= 1'b0;
MCAB_O <= 1;
end
WB_WRITING: begin
MADR_O[30:0] <= r_w_addr + rx_b1_offset[30:0];
MADR_O[31] <= 1'b1;
MCAB_O <= 1;
end
WB_INT_ACK: begin
MADR_O[30:0] <= `ACK_CYC_ADDR;
MADR_O[31] <= 1'b0;
MCAB_O <= 0;
end
WB_W_WAIT: begin
MADR_O[30:0] <= tx_b1_offset[30:0] + `DUMMY_READ_ADDR;
MADR_O[31] <= 1'b0;
MCAB_O <= 0;
end
default: begin
MADR_O[31:0] <= 0;
MCAB_O <= 1;
end
endcase
end

always@(negedge CLK_I)
begin
if(next_state == WB_IDLE)
begin
MSTB_O <= 1'b0;
MCYC_O <= 1'b0;
end
else
begin
MSTB_O <= 1'b1;
MCYC_O <= 1'b1;
end
end


always@(r_counter)
begin
r_counter_empty = (r_counter > 0)? 1'b0 : 1'b1;
end

pulse_gen read_ld_pulse
(
.Trigger (r_counter_empty),
.Pulse_Out (counter_loaded),
.Clock (CLK_I)
);


endmodule


The simulation works ok... but when i implement that on a Spartan III i got
a wird behavior on my FSM. For some reason the state keeps jumping from
IDLE to READING, and from READING to IDLE, but the r_counter is not
moving... so if i write 5 on r_counter.. it stay on 5 but the states keep
moving. Any idea of what could couse that? As i do not have chipscope i am
using 4 seven seg. display and 3 leds to debug. On the display i am looking
to the counter, and at the leds on the first 3 elements of the next_state
array, so i can see if it stay at IDLE or READING, but the result is that i
can see that the the first and third led are ON, but not wih full power...
as it was being driven by a PWM signal, so i could supose that the FSM
keeps jumping between both states...

Any help please?

I will not give any further detail now becouse they are irrelevant as all
teh rest looks ok, and i can see the r_counter value...

Thank you!

---------------------------------------
Posted through http://www.FPGARelated.com
 
You really need to learn how to write verilog code correctly first.

Jon

---------------------------------------
Posted through http://www.FPGARelated.com
 
On Apr 18, 7:34 am, "maxascent"
<maxascent@n_o_s_p_a_m.n_o_s_p_a_m.yahoo.co.uk> wrote:
You really need to learn how to write verilog code correctly first.

Jon        

---------------------------------------        
Posted throughhttp://www.FPGARelated.com
I could manage to solve the problem, a guy from edaboard pointed me
the problem, i gorgot to latch the state at the FSM.

The code is dirt becouse i was crazy trying to debug it, but where
should i look for good pactices on writing verilog code?

Thank you!
 
You need to learn some of the nuances of Verilog.  I also don't
believe this
simulates properly.

First, the case statement that begins
    always@(state_machine or r_counter or tx_b_1_int or tx_b_2_int or
        write_done or int_ack_done or DATA_READY)
        begin
        tx_b_1_over = 1'b0;
        tx_b_2_over = 1'b0;
        rx_b_1_over = 1'b0;
        rx_b_2_over = 1'b0;
        case (state_machine)
        WB_IDLE :
            begin
            if(r_counter > 32'h00000000)
                begin
                next_state = WB_READING;
                end
            end
will infer latches.  This is usually bad.  Look in the synthesis
report (.syr) to see
if latches are being inferred.   Why is this happening? What logic
does the above
fragment need if r_counter == 0?

Second, ask yourself, "how does the state machine ever get to
WB_WRITING?

You need to completely review your code and think about what h/w it
will create.

Good luck!

John Providenza
John the WRITING state was not implemented yet, thats why it was over
there but never got activated, Sorry for the horrible code.

Thank you!
 

Welcome to EDABoard.com

Sponsor

Back
Top