Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Memory cache removed, SRAM module reimplemented
I've removed the cache, which required reimplementing the 8-bit SRAM controller built into the ZXUno. The core is not working now, something is not working and I still don't know what it is. I have carried out the simulation of the new SRAM module, both for writing and reading, I attach PDFs... the simulation results do not show errors in the timing of the signals and the results of din/dout, sram_a and sram_d . @gyurco, do you have any ideas?
- Loading branch information
Showing
4 changed files
with
123 additions
and
175 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,103 +1,90 @@ | ||
////////////////////////////////////////////////////////////////////////////////// | ||
// | ||
// Filename: sram.v | ||
// Description: SRAM 8-bit controller for the Next186 SoC PC project, | ||
// Version 1.0 | ||
// Creation date: Dec2016 | ||
// | ||
// Author: DistWave | ||
// | ||
// Based on SDRAM 16-bit controller from the Next186 SoC PC project by Nicolae Dumitrache | ||
///////////////////////////////////////////////////////////////////////////////// | ||
`timescale 1ns / 1ps | ||
|
||
module SRAM_8bit( | ||
input sys_CLK, // clock | ||
input [1:0]sys_CMD, // 00=nop, 01=write 256 bytes, 11=read 256 bytes | ||
input [18:0]sys_ADDR, // word address, multiple of 2 words (4 bytes) | ||
input [15:0]sys_DIN, // data input | ||
output reg [15:0]sys_DOUT, | ||
output reg sys_rd_data_valid = 0, // data valid out | ||
output reg sys_wr_data_valid = 0, // data valid in | ||
|
||
input sram_clk, | ||
output sram_n_WE, // SRAM #WE | ||
output reg [20:0]sram_ADDR, // SRAM address | ||
inout [7:0]sram_DATA // SRAM data | ||
); | ||
module SRAM_8bit ( | ||
input wire [20:0] addr, // IN [20:0] -> SRAM address [20:0] (up to 2MByte) | ||
output reg [31:0] dout, // OUT [31:0] -> DWORD from SRAM | ||
input wire [31:0] din, // IN [31:0] -> DWORD to SRAM | ||
input wire clk, // IN -> CPU Clock | ||
input wire mreq, // IN -> Read/Write request | ||
input wire [3:0] wmask, // IN [3:0] -> Byte to write | ||
output wire ce, // OUT -> To tell the Next186 CPU module to wait for read and/or write operations to complete | ||
|
||
reg [2:0]STATE = 0; | ||
reg [2:0]RET; // return state | ||
reg [6:0]DLY; // delay | ||
reg [1:0]sys_cmd_ack = 0; // command acknowledged | ||
reg [15:0]reg_din; | ||
reg [5:0]out_data_valid = 0; | ||
|
||
assign sram_DATA = out_data_valid[2] ? sram_ADDR[0] ? reg_din[15:8] : reg_din[7:0] : 8'hzz; | ||
assign sram_n_WE = out_data_valid[2] ? 0 : 1; | ||
|
||
reg [7:0]sram_data2; | ||
output reg [20:0] sram_a, // OUT -> SRAM address [20:0] | ||
inout wire [7:0] sram_d, // IN/OUT -> SRAM data [7:0] | ||
output reg sram_we_n = 1 // OUT -> SRAM #WE (1 bit) | ||
); | ||
|
||
|
||
reg [2:0] s_byte = 0; | ||
reg [3:0] status = 0; | ||
reg [7:0] s_din; | ||
reg s_mreq = 0; | ||
wire wr = |wmask; | ||
assign ce = (status == 0) && ~s_mreq; | ||
assign sram_d = sram_we_n ? 8'hZZ : s_din; | ||
|
||
always @(posedge sram_clk) begin | ||
sram_data2 <= sram_DATA; | ||
case(STATE) | ||
0: begin | ||
if(|sys_CMD) begin | ||
sram_ADDR <= {sys_ADDR[18:0], 2'b00}; | ||
end | ||
end | ||
1: begin | ||
if ((sys_rd_data_valid == 1'b1) || (out_data_valid[2] == 1'b1)) begin | ||
sram_ADDR <= sram_ADDR + 1'b1; | ||
end | ||
end | ||
7: begin | ||
if(sys_cmd_ack[1]) begin | ||
sram_ADDR <= sram_ADDR + 1; | ||
end | ||
end | ||
endcase | ||
end | ||
|
||
|
||
always @(posedge sys_CLK) begin | ||
STATE <= 1; | ||
reg_din <= sys_DIN; | ||
out_data_valid <= {out_data_valid[1:0], sys_wr_data_valid}; | ||
DLY <= DLY - 1; | ||
sys_DOUT <= {sram_DATA, sram_data2}; | ||
|
||
case(STATE) | ||
0: begin | ||
sys_rd_data_valid <= 1'b0; | ||
if(|sys_CMD) begin | ||
sys_cmd_ack <= sys_CMD; | ||
STATE <= 5; | ||
end | ||
else begin | ||
sys_cmd_ack <= 2'b00; | ||
STATE <= 0; | ||
always @(posedge clk) begin | ||
case(status) | ||
0: begin | ||
if (mreq) begin | ||
s_mreq = 1; | ||
sram_a <= {addr[20:2], 2'b00}; | ||
s_byte <= 0; | ||
if (wr) | ||
status <= 2; | ||
else status <= 1; | ||
end | ||
|
||
end | ||
1: begin | ||
sram_a <= sram_a + 1; | ||
s_byte <= s_byte + 1; | ||
case(s_byte) | ||
0: | ||
dout[7:0] <= sram_d; | ||
1: | ||
dout[15:8] <= sram_d; | ||
2: | ||
dout[23:16] <= sram_d; | ||
3: begin | ||
dout[31:24] <= sram_d; | ||
s_mreq = 0; | ||
status <= 0; | ||
end | ||
endcase | ||
end | ||
2: begin | ||
status <= 3; | ||
case(s_byte) | ||
0: begin | ||
s_din = din[7:0]; | ||
sram_we_n = ~wmask[0]; | ||
end | ||
1: begin | ||
s_din = din[15:8]; | ||
sram_we_n = ~wmask[1]; | ||
end | ||
2: begin | ||
s_din = din[23:16]; | ||
sram_we_n = ~wmask[2]; | ||
end | ||
3: begin | ||
s_din = din[31:24]; | ||
sram_we_n = ~wmask[3]; | ||
end | ||
endcase | ||
end | ||
1: begin | ||
if(DLY == 3) sys_wr_data_valid <= 1'b0; | ||
if(DLY == 0) STATE <= RET; // NOP for DLY clocks, return to RET state | ||
end | ||
5: begin // read/write | ||
RET <= 7; | ||
if(sys_cmd_ack[1]) begin // read | ||
STATE <= 7; | ||
end else begin // write | ||
DLY <= 1; | ||
sys_wr_data_valid <= 1'b1; | ||
end | ||
end | ||
7: begin // init read/write phase | ||
if(sys_cmd_ack[1]) begin | ||
sys_rd_data_valid <= 1'b1; | ||
end | ||
RET <= 0; | ||
DLY <= sys_cmd_ack[1] ? 128 - 2 : 128 - 1; | ||
end | ||
3: begin | ||
sram_we_n = 1; | ||
sram_a <= sram_a + 1; | ||
s_byte <= s_byte + 1; | ||
if (s_byte == 4) begin | ||
s_mreq = 0; | ||
status <= 0; | ||
end | ||
else status <= 2; | ||
end | ||
endcase | ||
end | ||
endmodule | ||
|
||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
a7f1293
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, but the cache/memory architecture of this core is mostly a black box for me. And it doesn't help that the CPU's bus is far from the original, tightly coupled with the cache, and even with the display RAM access.
a7f1293
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't worry, it had to be tried ;-), I'll keep thinking how to solve it. Thanks!
a7f1293
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is true that the BIU module is very difficult to digest. Even something that could be simpler, such as removing or simply reducing the 16-byte instruction cache/queue, something I'm also interested in... I can't get it.
Can you think of any way to do the latter that I propose? At least reduce the instruction queue? For me it would be a step forward.
a7f1293
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you want to remove the cache at all? The CPU won't be cycle exact anyway. If you want that, maybe you should use a different CPU, like https://github.com/MicroCoreLabs/Projects/tree/master/MCL86 (used in the Q*bert core already, so it works).
With the cache, you can throttle the CPU in case of cache miss with the CE signal, as I did:
https://github.com/gyurco/Next186/blob/master/rtl/cache_controller.sv#L190
a7f1293
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't rule out the use of MCL86, in fact I already thought about it because the truth is that for my purpose, Next186 is turning out to be very unstable.
It is not an easy task, since I would like to take advantage of the rest of the Next186 modules, such as timer, etc... but in the end, I will have no other option.
Another project that I had in mind that could perhaps be used is the Zet processor:
https://github.com/marmolejo/zet
a7f1293
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the existing PIT/PIC/etc. modules can be used with another CPU, too, since their bus interface are ordinary and universal.
a7f1293
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Meanwhile I've added the basic CGA modes to the original fork. Now BIOS text and pixel draw functions must be implemented, as it's used by some games (BIOS text drawing even used in VGA games).
a7f1293
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I have seen it. That's great!