Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 module test(address_in, data_io, wr, rd, reset ); input [2:0] address_in; inout [2:0] data_io; input wr, rd, reset; reg [2:0] data_in; reg [2:0] data_out; reg [2:0] address; reg [2:0] level[2:0]; reg [3:0] state; reg [3:0] last_state; reg wr_flag; reg rd_flag; reg last_wr_state; reg last_rd_state; reg [2:0] rd_state; wire n_rd; assign data_io = (!rd && !reset) ? data_out : 3'bz; clock master_clock(m_clock); //instantiate clock //cl = output always @ (posedge m_clock) begin if (wr != last_wr_state) //some edge on write line begin last_wr_state = wr; //positive edge, latch address and data if (wr) begin data_in = data_io; address = address_in; wr_flag = 1; end end else begin if (wr_flag) begin wr_flag = 1'b0; *****THIS FAILS HERE level[address] = data_in; //data and address latched earlier **It works like this instead level[1] = data_in; end else if (!rd) begin if (rd_state <= 3'd3) begin rd_state = rd_state + 1; //wait some clock cycles for address to stabilize end else if (rd_state == 3'd3) //after n clocks since neg edge on bus, latch internal data to address begin rd_state = rd_state + 1; data_out= level[address_in]; end else begin data_out= data_out; end end else begin state <= state; end end end endmodule
data_out= data_out;
end
end
else
begin
state <= state;
module bus_interface(address_in, data_io, wr, rd, reset );
parameter ADDRESS_WIDTH= 4;
parameter DATA_WIDTH = 3;
parameter CHANNELS = 4;
input [ADDRESS_WIDTH-1:0] address_in;
inout [DATA_WIDTH-1:0] data_io;
input wr, rd, reset;
reg [DATA_WIDTH-1:0] data_in;
reg [DATA_WIDTH-1:0] data_out;
reg [DATA_WIDTH-1:0] address;
reg [DATA_WIDTH-1:0] level[CHANNELS-1:0];
reg [3:0] state;
reg [3:0] last_state;
reg wr_flag;
reg rd_flag;
reg last_wr_state;
reg last_rd_state;
reg [2:0] rd_state;
wire n_rd;
assign data_io = (!rd && !reset) ? data_out : 3'bz;
clock master_clock(m_clock); //instantiate clock //cl = output
always @ (posedge m_clock)
begin
if (reset)
begin
wr_flag = 1'b0;
rd_flag = 1'b0;
last_wr_state = wr;
last_rd_state = rd;
rd_state = 3'd4;
level[0] = 3'd0;
level[1] = 3'd1;
level[2] = 3'd2;
level[3] = 3'd3;
address = 3'd0;
data_in = 3'd0;
// data_out = 3'bz;
state = 3'd0;
address1 = 1;
end
else if (wr != last_wr_state) //some edge on write line
begin
last_wr_state = wr; //positive edge, latch address and data
if (wr)
begin
data_in = data_io;
address = address_in;
wr_flag = 1;
end
end
else if (rd != last_rd_state) //some edge on read line
begin
last_rd_state = rd;
if (!rd) //negative edge
begin
rd_state = 3'd0;
end
end
else
begin
if (wr_flag)
begin
wr_flag = 1'b0;
**The problem----> level[address] = data_in; //data and address latched earlier
end
else if (!rd)
begin
if (rd_state <= 3'd3)
begin
rd_state = rd_state + 1; //wait some clock cycles for address to stabilize
end
else if (rd_state == 3'd3) //after n clocks since neg edge on bus, latch internal data to address
begin
rd_state = rd_state + 1;
data_out= level[address_in];
end
else
begin
data_out= data_out;
end
end
else
begin
// data_out = 3'bz;
state <= state;
end
end
// endcase
end
endmodule
if (rd_state <= 3'd3)
begin
rd_state <= rd_state + 1;
end
else if (rd_state == 3'd3)
begin
rd_state <= rd_state + 1;
data_out <= level[address_in];
end
reg wr_flag;
always @(posedge clk)
begin
wr_flag <= wr
if (wr && !wr_flag) //positive edge
level[address_in] = data_io;
end
stacksmith said:2) Write code - try using case statements, for each state, how the next state is figured out.
// data_out = 3'bz;
module array_test(address_in, data_io, wr);
input [2:0] address_in;
input [2:0] data_io;
input wr;
reg [2:0] level[2:0];
reg [2:0] address_latched;
reg [2:0] data_latched;
clock master_clock(m_clock); //instantiate clock //cl = output
always @ (posedge m_clock)
begin
if (!wr) //write line = low, latch address and data
begin
data_latched <= data_io;
address_latched <= address_in;
end
else
begin //wr line high, write previous address and data to level[x]
Does not work--->> level[address_latched] <= data_latched; //data and address latched earlier
end
end
endmodule
reg [2:0] level[2:0];
reg [2:0] level[0:2];
Ah, that's beautiful!
One thing that jumps out immediately is your declaration
is usually written asCode:reg [2:0] level[2:0];
Buses are high-low, arrays low-high. I don't have the docs handy, but it might confuse the simulator.Code:reg [2:0] level[0:2];
address_latched <= address_in;
Thank you very much for clearing up the forest. I can see trees now!
A good candidate would be to check out your address_in signal. You are probably generating that with a testbench? What is the value of that during the testbench?
The reason I ask is you said you do get a result when you hardcode it with level[2] <= data_latched . That would mean that at least at that time data_latched has some useful values. So the main suspect would then be this bit.
Code:address_latched <= address_in;
I am assuming that this portion actually gets hit (read: wr is low), but that seems a reasonable assumption for now. What I mean is: for you to check, for me to assume right now since I don't see the rest of your code.
Anyways, since address_latched most probably contains Xs (or U's, Z's depending on your exact error), with your current code that would mean that address_in is X's, which means that you most probably forgot something one level up. Either you did not initialize it, or you forgot to connect it altogether.
And if you do have a testbench and after this you haven't solved it, could you post the testbench code + screenshot of waveform?
Some more advice that will probably not help:
Whenever you have a conditional, each leg of the conditional should assign the same destinations. Otherwise, unknown to you, latches and muxes will be inserted into your circuit.
For instance, one part of your "if" statement assigns data_latched and address_latched. The other side does not. So what happens if the condition is false? data_latched and address_latched cannot be assigned, so either an enable will be generated for the register, or some kind of a latch will be added, with a 2-1 mux in front of your register, so the same data can be clocked in. Generally, that is bad, especially if you are not aware of it.
Same goes for your level[address_latched] construct. Normally it would be a mux and a register. But because you are not explicitly setting it for some clocks, some sort of a circuit - probably another mux and a latch will be added.
You should also clearly understand the difference between latches and flip-flops. Your synchronous logic uses flip-flops. A latch is an asynchronous construct that holds the last value stored. It can mean trouble. Your naming conventions - data_latched etc. actually probably mean data_flopped or data_registered...
module array_test
#( parameter DATA_W = 8, ADDR_W = 4, MEM_D = 2**ADDR_W )
(
input [ADDR_W-1:0] address_in,
inout [DATA_W-1:0] data_io, //changed input->inout
input wr, rd,
input rd, m_clock // added
);
reg [DATA_W-1:0] level[0:MEM_D-1];
reg [ADDR_W-1:0] address_latched;
reg [DATA_W-1:0] data_latched;
reg [DATA_W-1:0] data_out;
reg wr_reg, // added
rd_reg;
always @(posedge m_clock) // added
begin
wr_reg <= wr;
rd_reg <= rd;
end
//clock master_clock(m_clock); //instantiate clock //cl = output // commented out
assign data_io = rd_reg ? data_out : {DATA_W{1'bz}}; //added
always @ (posedge m_clock)//slightly changed
begin
if (!wr)
begin
data_latched <= data_io;
address_latched <= address_in;
end
else
if (!wr_reg)
level[address_latched] <= data_latched;
data_out <= level[address_in];
end
endmodule
In the simulation, you are latching an address value of 3, but level covers an index range of 0 to 2 only. So data is stored to non-existing memory.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?