- Joined
- Jan 22, 2008
- Messages
- 53,107
- Helped
- 14,792
- Reputation
- 29,871
- Reaction score
- 14,291
- Trophy points
- 1,393
- Location
- Bochum, Germany
- Activity points
- 301,057
I hate simulating. Usually I start with a simplified version (here I would have tried 1 1-bit-wide bus), make a circuit conected to switches and LEDs and make sure it works.
// OLD:
reg [2:0] level[2:0];
// NEW
reg [2:0] level[0:7];
//reg [2:0] level[7:0]; // or this if you like a decrementing address range
userx2 you've changed data_io from inout to input
in your last attempt, I wonder how you can test the design
with no output ports;
try this version:
once you have something working you can do yourCode: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
experiments;
j.a
what we need is this:
reg [DATA_W-1:0] level[3'd0: 3'd3] ; (ignore the exact ranges)
Now I can't translate that into parameters. I have tried all morning.
Here is the non working result:
reg [DATA_W-1:0] level[{ADDR_W{'b0}}: {ADDR_W{'d{LEVELS}}}];
The compiler seems to assume that the 0:3 are intergers of size 31 bits. When we then write to the level[] with address that is only 3 bits wide, it just does not work.
reg [15:0] level[0:255];
reg [15:0] level[8'd0:8'd255];
module bus_interface
#( parameter ADDR_W= 4, DATA_W = 3, LEVELS = 4, MEM_D = 2**ADDR_W)
(
input [ADDR_W-1:0] address_in,
inout [DATA_W-1:0] data_io,
input wr, rd, reset, m_clock
);
reg [DATA_W-1:0] data_latched;
reg [DATA_W-1:0] data_out;
reg [ADDR_W-1:0] address_latched;
reg [DATA_W-1:0] level[0:15];
reg wr_reg;
reg rd_reg;
assign data_io = (!rd && !reset) ? data_out : {DATA_W{'bz}};
//clock master_clock(m_clock); //instantiate clock //cl = output
always @(posedge m_clock)
begin
wr_reg <= wr;
rd_reg <= rd;
end
always @(posedge m_clock)
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
module bus_interface
#( parameter ADDR_W= 4, DATA_W = 3, LEVELS = 4, MEM_D = 2**ADDR_W)
(
input [ADDR_W-1:0] address_in,
inout [DATA_W-1:0] data_io,
input wr, rd, reset, m_clock
);
reg [DATA_W-1:0] data_latched;
reg [DATA_W-1:0] data_out;
reg [ADDR_W-1:0] address_latched;
reg [DATA_W-1:0] level[0:15];
reg wr_reg;
reg rd_reg;
assign data_io = (!rd && !reset) ? data_out : {DATA_W{'bz}};
//clock master_clock(m_clock); //instantiate clock //cl = output
initial begin
// some initial data just for the fun of it.
level[0] <= 3'b101;
level[1] <= 3'b010;
level[2] <= 3'b111;
level[15] <= 3'b001;
end
always @(posedge m_clock)
begin
wr_reg <= wr;
rd_reg <= rd;
end
always @(posedge m_clock)
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
module bus_interface
#( parameter ADDR_W= 4, DATA_W = 3, CHANNELS = 12)
(
output [DATA_W-1:0] level[0:CHANNELS-1],
input [ADDR_W-1:0] address_in,
inout [DATA_W-1:0] data_io,
input wr, rd, reset, m_clock
);
As far I know, two-dimensional vectors aren't supported for Verilog module interfaces. You need to flatten it to 1-D, just a matter of index manipulations in a generate loop. System Verilog can do structured interface objects, also VHDL.
It's the precise term used in the IEEE 1364 specification, so I would expect a serious Verilog text book to know about it. Possibly not an "Easy Verilog" book restricting itself to a subset of the language.What is a generate loop? My pdf book does not have any reference to that at all.
module bus_interface
#( parameter ADDR_W= 4, DATA_W = 3, CHANNELS = 12, MEM_SIZE_BITS = CHANNELS * DATA_W )
(
output [MEM_SIZE_BITS-1:0] level,
input [ADDR_W-1:0] address_in,
inout [DATA_W-1:0] data_io,
input wr, rd, reset, m_clock
);
reg [DATA_W-1:0] data_latched;
reg [DATA_W-1:0] data_out;
reg [ADDR_W-1:0] address_latched;
reg [MEM_SIZE_BITS-1:0] level;
reg wr_reg;
reg rd_reg;
assign data_io = (!rd && !reset) ? data_out : {DATA_W{'bz}};
reg [ADDR_W-1:0] i;
//**DOES NOt WORK
initial begin
for (i=0; i<CHANNELS; i=i+1)
begin
level[((i+1)*DATA_W)-1: (i*DATA_W)] = {DATA_W{'b0}};
end
end
//**Likewise this does not work either"
genvar i;
generate
for (i=0; i<CHANNELS; i=i+1)
begin
level[((i+1)*DATA_W)-1: (i*DATA_W)] = {DATA_W{'b0}};
end
endgenerate
always @(posedge m_clock)
begin
wr_reg <= wr;
rd_reg <= rd;
end
always @(posedge m_clock)
begin
if (!wr)
begin
data_latched <= data_io;
address_latched <= address_in;
end
else
if (!wr_reg)
begin
//**DOES NOT WORK EITHER
level[((address_latched+1)*DATA_W)-1: (address_latched*DATA_W)] <= data_latched;
end
end
endmodule
You are trying a third kind of variable part-select.There are two types of part-selects, a constant part-select and an indexed part-select.
Doesn't work isn't really a clear problem report.
Verilog users will recognize that you are trying a vector part-select syntax, that isn't supported by the language.
The Verilog specification says:
You are trying a third kind of variable part-select.
Please review your Verilog text book or previous edaboard discussions about indexed part-select and you'll see how it's supposed to work.
level[((i+1)*DATA_W)-1 -: DATA_W] = {DATA_W{'b0}};
module bus_interface
#( parameter ADDR_W = 4, DATA_W = 3, CHANNELS = 12,
MEM_SIZE_BITS = CHANNELS * DATA_W )
(
output reg [MEM_SIZE_BITS-1:0] level,
input [DATA_W-1:0] data_in,
input [ADDR_W-1:0] address_in,
input wr, clk
);
/* assume address_in = 0 selects bits 2-0 in 'level',
= 1 bits 5-3
= 2 bits 8-6 etc */
initial level = {MEM_SIZE_BITS{1'b0}};
integer i;
always @(posedge clk)
if (!wr)
for ( i=0;i<DATA_W; i=i+1 )
level[i + address_in * DATA_W ] <= data_in[i];
endmodule
Yes, besides the wrong part select syntax the expression in the generate loop is incorrect. Continuous assignments are opened with the keyword assign.I should have stated that the generate loop results in a 'syntax error near ='
The intial begin method states that 'i is not a constant' and so does the level[....] = .....
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?