OK, after testing, have you figured out why the endian option is a bad thing?
Do you have a better solution to cover all possibilities?
How is that possible?
It's working fine on my side....
What did you do?
If I don't let you do this, you will always rely on me...
I even told you the 1 line to add to the 'setup_z80_to_DDR3.do' and 'run_z80_to_DDR3.do'.
Everything else you had except for the ' ' { ' error once removed, it should have worked after typing:
do setup_z80_to_DDR3.do
To be safe, close modelsim, delete the 'work' directory and delete modelsim.ini, and delete vlog.opt and delete vsim.wlf to flush everything blank.
before sending out any Modelsim .zip, please delete TB_v15.code-workspace and delete the 'work' directory and delete modelsim.ini, and delete vlog.opt and delete vsim.wlf to flush everything blank. You just want a clean tiny project.
And what you sent me, (though I did the deleting first) seems to run completely fine.
Do you have the project in a folder where modelsim has write privileges?
What about the C:\tmp folder for the DDR3 bank files?
(If it is the C:\tmp write privileges, then I know you never ran a single DDR3 testbench of mine.)
@LOG_FILE Z80_cmd_stimulus_log.txt
@RESET
@CMD WM 0000 aa Write to memory address
@CMD WM 0001 11 Write to memory address
@CMD WM 0002 22 Write to memory address
@CMD WM 0003 33 Write to memory address
@CMD WM 0004 44 Write to memory address
@CMD WM 0005 55 Write to memory address
@CMD WM 0006 66 Write to memory address
@CMD WM 0007 77 Write to memory address
@CMD WM 0010 10 Write to memory address
@CMD WM 0020 20 Write to memory address
@CMD WM 0030 30 Write to memory address
@CMD WM 0040 40 Write to memory address
@CMD WM 0050 50 Write to memory address
@CMD WM 1110 BB Write to memory address
@CMD WM 2210 CC Write to memory address
@CMD WM 3310 DD Write to memory address
)(
input RESET,
input CLK,
input WE,
input [PORT_ADDR_SIZE-1:0] ADDR_IN,
input [PORT_CACHE_BITS-1:0] DATA_IN,
input [PORT_CACHE_BITS/8-1:0] WMASK,
output reg [ 7:0] HW_REGS_8bit[0:(2**HW_REGS_SIZE-1)]
output wire [ 15:0] HW_REGS_16bit[0:(2**HW_REGS_SIZE-1)]
output wire [ 31:0] HW_REGS_32bit[0:(2**HW_REGS_SIZE-1)]
);
Did you tune the Z80 read cache / WAIT output timing?
Did you solve the new HW_REGS code issue?
Did you tune the Z80 read cache / WAIT output timing?
Did you solve the new HW_REGS code issue?
(BTW: I do not have a "D:\tmp" drive. Also, isn't there a way to define the tmp folrder in the code instead of modifying Micron's ddr3.v source code + make that folder in the same folder as the work directory...)
Did you solve the new HW_REGS code issue?
Looks like it was writing each 16-bit value to the wrong address - i.e. for the first write (0xAA), it should have been writing to address 0, it was writing to 15-(the required address). I don't know why it would do that and I'm struggling to get my head around what's going on with [i^ENDIAN] and OR-ing values together etc.(BTW: I do not have a "D:\tmp" drive. Also, isn't there a way to define the tmp folrder in the code instead of modifying Micron's ddr3.v source code + make that folder in the same folder as the work directory...)
Fixed this - although it still required an alteration to Micron's ddr3.v source code. Changed the path from "D:\tmp" to just ".\tmp" - it now uses a folder called 'tmp' in the project directory. Can find no reference to a command that allows me to change the tmp directory path outside of the source code, and frankly don't have the time to hunt it down when I have a working solution that (hopefully) won't cause issues at anyone else's end either.
Am I going along the right path with the changes I've made in the attached files? Haven't sorted out the resets for the 16 and 32-bit regs, plus it all seems a bit wasteful in terms of gates duplicating all that data, but I'm sure there's probably a much simpler way of doing it all that you've got.
Next, work out why the 'ENDIAN' only messes up then entire HW_REG system, why you need to get rid of it and why making new IO port with the same output reg renamed to 8bit and these new assigned output wires would help provide a better solution:Code: [Select])(
input RESET,
input CLK,
input WE,
input [PORT_ADDR_SIZE-1:0] ADDR_IN,
input [PORT_CACHE_BITS-1:0] DATA_IN,
input [PORT_CACHE_BITS/8-1:0] WMASK,
output reg [ 7:0] HW_REGS_8bit[0:(2**HW_REGS_SIZE-1)]
output wire [ 15:0] HW_REGS_16bit[0:(2**HW_REGS_SIZE-1)]
output wire [ 31:0] HW_REGS_32bit[0:(2**HW_REGS_SIZE-1)]
);
I said assigned wires, not new regs.
IE:
for loop
assign HW_REGS_16bit[ i ] = {HW_REGS_8bit[ i+0 ],HW_REGS_8bit[ i+1 ]};
similar for the 32bit assigns.
Swap the +0 and +1 depending on the endian setting.
There was no way I was going to work out how to invert the address like that.
assign HW_Regs_16bit = enable ? { HW_REGS__8bit[( ADDR_IN[HW_REGS_SIZE-1:0] )], HW_REGS__8bit[(( ADDR_IN[HW_REGS_SIZE-1:0] ) + 1 )] } : 16'b0 ;
assign HW_Regs_32bit = enable ? { HW_REGS__8bit[( ADDR_IN[HW_REGS_SIZE-1:0] )], HW_REGS__8bit[(( ADDR_IN[HW_REGS_SIZE-1:0] ) + 1 )], HW_REGS__8bit[(( ADDR_IN[HW_REGS_SIZE-1:0] ) + 2 )], HW_REGS__8bit[(( ADDR_IN[HW_REGS_SIZE-1:0] ) + 3 )] } : 32'b0 ;
I'm missing something or doing something wrong here with the assigns. According to ModelSim, the 16bit and 32bit HW_Regs are constantly hi-z and their values never change?Code: [Select]assign HW_Regs_16bit = enable ? { HW_REGS__8bit[( ADDR_IN[HW_REGS_SIZE-1:0] )], HW_REGS__8bit[(( ADDR_IN[HW_REGS_SIZE-1:0] ) + 1 )] } : 16'b0 ;
assign HW_Regs_32bit = enable ? { HW_REGS__8bit[( ADDR_IN[HW_REGS_SIZE-1:0] )], HW_REGS__8bit[(( ADDR_IN[HW_REGS_SIZE-1:0] ) + 1 )], HW_REGS__8bit[(( ADDR_IN[HW_REGS_SIZE-1:0] ) + 2 )], HW_REGS__8bit[(( ADDR_IN[HW_REGS_SIZE-1:0] ) + 3 )] } : 32'b0 ;
Both outputs should only show a value if enable is high. Is that preferable to just outputting a value no matter what?
IE:
for loop
assign HW_REGS_16bit[ i ] = {HW_REGS_8bit[ i+0 ],HW_REGS_8bit[ i+1 ]};
always_comb begin
for (i = big_endian ; i < (total_size-1) ; i ++ ) HW_REGS_16bit[ i ] = {HW_REGS_8bit[ i+little_endian ],HW_REGS_8bit[ i+big_endian ]};
end
Im sure I might have flipped around an endian or 2...integer x ;
always_comb begin
for (x = 0; x < PORT_CACHE_BITS/8 - 1; x = x + 2) begin
HW_REGS_16bit[x] = { HW_REGS__8bit[x+0], HW_REGS__8bit[x+1] } ;
end
for (x = 0; x < PORT_CACHE_BITS/8 - 1; x = x + 4) begin
HW_REGS_32bit[x] = { HW_REGS__8bit[x+0], HW_REGS__8bit[x+1], HW_REGS__8bit[x+2], HW_REGS__8bit[x+3] } ;
end
end
integer i ;
always @( posedge CLK ) begin
if ( RESET ) begin
// reset registers to initial values
for (i = 0; i < RST_PARAM_SIZE; i = i + 1) begin
HW_REGS__8bit[{RESET_VALUES[i][29:17], 1'b0}] <= RESET_VALUES[i][ 7:0] ;
HW_REGS__8bit[{RESET_VALUES[i][29:17], 1'b1}] <= RESET_VALUES[i][15:8] ;
end
end
else
begin
for (i = 0; i < PORT_CACHE_BITS/8; i = i + 1) begin
if (valid_wr && WMASK[i]) begin
HW_REGS__8bit[( ADDR_IN[HW_REGS_SIZE-1:0] | (i^(PORT_CACHE_BITS/8-1)) )] <= DATA_IN[i*8+:8] ;
end
end
end
end
integer x;
always_comb begin
for (x = 0; x < PORT_CACHE_BITS/8 - 1; x = x + 2) begin
HW_REGS_16bit[x/2] = { HW_REGS__8bit[x+0], HW_REGS__8bit[x+1] } ;
end
for (x = 0; x < PORT_CACHE_BITS/8 - 1; x = x + 4) begin
HW_REGS_32bit[x/4] = { HW_REGS__8bit[x+0], HW_REGS__8bit[x+1], HW_REGS__8bit[x+2], HW_REGS__8bit[x+3] } ;
end
end
Code: [Select]integer x ;
always_comb begin
for (x = 0; x < PORT_CACHE_BITS/8 - 1; x = x + 2) begin
HW_REGS_16bit[x] = { HW_REGS__8bit[x+0], HW_REGS__8bit[x+1] } ;
end
for (x = 0; x < PORT_CACHE_BITS/8 - 1; x = x + 4) begin
HW_REGS_32bit[x] = { HW_REGS__8bit[x+0], HW_REGS__8bit[x+1], HW_REGS__8bit[x+2], HW_REGS__8bit[x+3] } ;
end
end
parameter string ENDIAN = "Big Endian", // Enter "B****" for Big Endian, anything else for Little Endian.
......
localparam endian_h16 = (ENDIAN[0] == "B") ? 1 : 0 ;
localparam endian_l16 = (ENDIAN[0] == "B") ? 0 : 1 ;
localparam endian_h32 = (ENDIAN[0] == "B") ? 3 : 0 ;
localparam endian_m32 = (ENDIAN[0] == "B") ? 2 : 1 ;
localparam endian_n32 = (ENDIAN[0] == "B") ? 1 : 2 ;
localparam endian_l32 = (ENDIAN[0] == "B") ? 0 : 3 ;
.......
for (x = 0; x < [color=red](HW_REGS_SIZE**2)[/color] - 3; x = x + 1) begin // The -3 means the final 3 bytes cannot be used as wide words as they would exceed the HW_REGS_8bit final address.
HW_REGS_16bit[x] = { HW_REGS_8bit[x+endian_h16], HW_REGS_8bit[x+endian_l16] } ;
HW_REGS_32bit[x] = { HW_REGS_8bit[x+endian_h32], HW_REGS_8bit[x+endian_m32], HW_REGS_8bit[x+endian_n32], HW_REGS_8bit[x+endian_l32] } ;
end