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