summaryrefslogtreecommitdiff
path: root/rtl/core/mmu
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-10-15 19:31:55 -0600
committerAlejandro Soto <alejandro@34project.org>2022-10-15 19:31:55 -0600
commitec152d814af82524cf68df95d7f06b9b70c0d0d0 (patch)
tree417ad3c693f0618dd9609ffef6028fa0a955fee2 /rtl/core/mmu
parent7d95ff01bcd8c42efe118fd1bddaabfca0e937eb (diff)
Rework bus architecture
Diffstat (limited to '')
-rw-r--r--rtl/core/mmu/mmu.sv64
1 files changed, 46 insertions, 18 deletions
diff --git a/rtl/core/mmu/mmu.sv b/rtl/core/mmu/mmu.sv
index 9d118c1..8d3b909 100644
--- a/rtl/core/mmu/mmu.sv
+++ b/rtl/core/mmu/mmu.sv
@@ -27,18 +27,26 @@ module core_mmu
DATA
} master, next_master;
+ logic active, hold_start, hold_write, hold_issue, hold_free, transition;
+ ptr hold_addr;
+ word hold_data_wr;
+
//TODO
assign insn_data_rd = bus_data_rd;
assign data_data_rd = bus_data_rd;
always_comb begin
next_master = master;
- if(bus_ready) begin
- if(insn_start)
- next_master = INSN;
- else if(data_start)
- next_master = DATA;
- end
+ if(bus_ready || !active)
+ unique case(master)
+ DATA: next_master = data_start ? DATA : INSN;
+ INSN: next_master = !data_start && !hold_start ? INSN : DATA;
+ endcase
+
+ // Causa UNOPTFLAT en Verilator con assign
+ transition = master != next_master;
+ hold_issue = transition && hold_start;
+ hold_free = transition || !hold_start;
insn_ready = 0;
data_ready = 0;
@@ -51,36 +59,56 @@ module core_mmu
unique case(next_master)
INSN: begin
bus_addr = insn_addr;
+ bus_write = 0;
+ bus_start = insn_start;
bus_data_wr = {32{1'bx}};
end
DATA: begin
bus_addr = data_addr;
+ bus_write = data_write;
+ bus_start = data_start;
bus_data_wr = data_data_wr;
end
endcase
+
+ if(hold_issue) begin
+ bus_addr = hold_addr;
+ bus_write = hold_write;
+ bus_start = 1;
+ bus_data_wr = hold_data_wr;
+ end
end
always @(posedge clk) begin
master <= next_master;
+ active <= bus_start || (active && !bus_ready);
- unique case(next_master)
- INSN: begin
- bus_start <= insn_start;
- bus_write <= 0;
- end
+ if(hold_free)
+ unique case(next_master)
+ INSN: begin
+ hold_start <= data_start;
+ hold_addr <= data_addr;
+ hold_write <= data_write;
+ hold_data_wr <= data_data_wr;
+ end
- DATA: begin
- bus_start <= data_start;
- bus_write <= data_write;
- end
- endcase
+ DATA: begin
+ hold_start <= insn_start;
+ hold_addr <= insn_addr;
+ hold_write <= 0;
+ end
+ endcase
end
initial begin
master = INSN;
- bus_start = 0;
- bus_write = 0;
+ active = 0;
+
+ hold_addr = 30'b0;
+ hold_start = 0;
+ hold_write = 0;
+ hold_data_wr = 0;
end
endmodule