summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
Diffstat (limited to 'rtl')
-rw-r--r--rtl/cache/cache.sv2
-rw-r--r--rtl/cache/cache_control.sv45
-rw-r--r--rtl/cache/defs.sv4
-rw-r--r--rtl/core/arm810.sv11
-rw-r--r--rtl/core/control/control.sv2
-rw-r--r--rtl/core/control/ldst/ldst.sv5
-rw-r--r--rtl/core/core.sv9
-rw-r--r--rtl/core/mmu/arbiter.sv13
-rw-r--r--rtl/core/mmu/mmu.sv24
-rw-r--r--rtl/core/mmu/pagewalk.sv15
10 files changed, 110 insertions, 20 deletions
diff --git a/rtl/cache/cache.sv b/rtl/cache/cache.sv
index e62a326..29403e2 100644
--- a/rtl/cache/cache.sv
+++ b/rtl/cache/cache.sv
@@ -9,9 +9,11 @@ module cache
input ptr core_address,
input logic core_read,
core_write,
+ core_lock,
input word core_writedata,
input word_be core_byteenable,
output logic core_waitrequest,
+ output logic[1:0] core_response,
output word core_readdata,
//TODO
diff --git a/rtl/cache/cache_control.sv b/rtl/cache/cache_control.sv
index e4c2148..7186e95 100644
--- a/rtl/cache/cache_control.sv
+++ b/rtl/cache/cache_control.sv
@@ -10,8 +10,10 @@ module cache_control
input addr_index core_index,
input logic core_read,
core_write,
+ core_lock,
input line core_data_wr,
output logic core_waitrequest,
+ output logic[1:0] core_response,
input ring_req in_data,
input logic in_data_valid,
@@ -57,13 +59,22 @@ module cache_control
logic accept_snoop, end_reply, in_hold_valid, last_hop, lock_line, locked,
may_send, may_send_if_token_held, mem_begin, mem_end, mem_read_end, mem_wait,
- out_stall, wait_reply, replace, retry, send, send_inval, send_read,
- snoop_hit, set_reply, unlock_line, writeback;
+ monitor_acquire, monitor_commit, monitor_fail, out_stall, wait_reply, replace,
+ retry, send, send_inval, send_read, snoop_hit, set_reply, unlock_line, writeback;
ring_req in_hold, send_data, fwd_data, stall_data, out_data_next;
- addr_tag mem_tag;
- addr_index mem_index;
+ line monitor_data_rd, monitor_data_wr;
+ addr_tag mem_tag, monitor_tag;
+ addr_index mem_index, monitor_index;
+
+ /* Avalon p. 15:
+ * - 00: OKAY - Successful response for a transaction.
+ * - 10: SLVERR - Error from an endpoint agent. Indicates an unsuccessful transaction.
+ */
+ assign core_response = {monitor_fail, 1'b0};
+ assign monitor_commit = !core_lock || (monitor_tag == core_tag && monitor_index == core_index
+ && monitor_data_rd == data_rd);
assign mem_end = (mem_read || mem_write) && !mem_waitrequest;
assign mem_wait = (mem_read || mem_write) && mem_waitrequest;
@@ -118,6 +129,9 @@ module cache_control
end_reply = 0;
set_reply = 0;
+
+ monitor_fail = 0;
+ monitor_acquire = 0;
core_waitrequest = 1;
in_data_ready = !in_hold_valid;
@@ -136,7 +150,9 @@ module cache_control
index_rd = in_hold.index;
end
- CORE:
+ CORE: begin
+ monitor_acquire = core_read && core_lock;
+
if (replace) begin
state_wr = INVALID;
write_state = 1;
@@ -177,8 +193,10 @@ module cache_control
{EXCLUSIVE, 1'b1}: begin
state_wr = MODIFIED;
- write_data = 1;
- write_state = 1;
+ write_data = monitor_commit;
+ write_state = monitor_commit;
+
+ monitor_fail = !monitor_commit;
core_waitrequest = 0;
end
@@ -186,10 +204,13 @@ module cache_control
core_waitrequest = 0;
{MODIFIED, 1'b1}: begin
- write_data = 1;
+ write_data = monitor_commit;
+
+ monitor_fail = !monitor_commit;
core_waitrequest = 0;
end
endcase
+ end
SNOOP: begin
index_rd = in_hold.index;
@@ -373,6 +394,14 @@ module cache_control
mem_index <= index_wr;
mem_writedata <= data_rd;
end
+
+ if (monitor_acquire && !core_waitrequest) begin
+ monitor_tag <= core_tag;
+ monitor_index <= core_index;
+
+ monitor_data_rd <= data_rd;
+ monitor_data_wr <= data_rd;
+ end
end
endmodule
diff --git a/rtl/cache/defs.sv b/rtl/cache/defs.sv
index bfefb88..e21e587 100644
--- a/rtl/cache/defs.sv
+++ b/rtl/cache/defs.sv
@@ -13,8 +13,8 @@ typedef logic[31:0] word;
`endif
/* Tenemos 512MiB de SDRAM, el resto del espacio es I/O (uncached). Usamos
-* 512 líneas direct-mapped de 16 bytes cada una. El core solo realiza
-* operaciones alineadas. Por tanto, cada dirección de 32 bits consta de:
+ * 512 líneas direct-mapped de 16 bytes cada una. El core solo realiza
+ * operaciones alineadas. Por tanto, cada dirección de 32 bits consta de:
* - 2 bits que siempre son 0 (traducidos a byteenable por core)
* - 2 bits de offset (ya que para cache la unidad direccionable es la word)
* - 9 bits de index
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv
index f498a15..cfe202a 100644
--- a/rtl/core/arm810.sv
+++ b/rtl/core/arm810.sv
@@ -13,7 +13,9 @@ module arm810
output ptr bus_addr,
output logic bus_start,
bus_write,
+ bus_ex_lock,
input logic bus_ready,
+ bus_ex_fail,
input word bus_data_rd,
output word bus_data_wr,
output logic[3:0] bus_data_be,
@@ -24,8 +26,7 @@ module arm810
ptr branch_target, fetch_insn_pc, fetch_head, insn_addr;
word fetch_insn;
- logic explicit_branch, fetch_nop, fetch_abort, stall,
- flush, prefetch_flush, insn_start;
+ logic explicit_branch, fetch_nop, fetch_abort, stall, flush, prefetch_flush;
//TODO
assign prefetch_flush = halt;
@@ -75,6 +76,8 @@ module arm810
.mem_write(data_write),
.mem_ready(data_ready),
.mem_fault(data_fault),
+ .mem_ex_lock(data_ex_lock),
+ .mem_ex_fail(data_ex_fail),
.mem_data_rd(data_data_rd),
.mem_data_wr(data_data_wr),
.mem_data_be(data_data_be),
@@ -173,8 +176,8 @@ module arm810
word data_data_rd, data_data_wr, insn_data_rd;
logic[3:0] data_data_be;
- logic data_start, data_write, data_ready, insn_ready,
- data_fault, insn_fault, data_user;
+ logic data_start, insn_start, data_write, data_ready, insn_ready,
+ data_fault, insn_fault, data_user, data_ex_lock, data_ex_fail;
core_mmu mmu
(
diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv
index ed0a1e1..6090f2d 100644
--- a/rtl/core/control/control.sv
+++ b/rtl/core/control/control.sv
@@ -25,6 +25,7 @@ module core_control
input logic c_shifter,
mem_ready,
mem_fault,
+ mem_ex_fail,
input word mem_data_rd,
input logic mul_ready,
input word mul_q_hi,
@@ -62,6 +63,7 @@ module core_control
output logic[3:0] mem_data_be,
output logic mem_start,
mem_write,
+ mem_ex_lock,
mem_user,
output word mul_a,
mul_b,
diff --git a/rtl/core/control/ldst/ldst.sv b/rtl/core/control/ldst/ldst.sv
index bb057bb..0e0a39c 100644
--- a/rtl/core/control/ldst/ldst.sv
+++ b/rtl/core/control/ldst/ldst.sv
@@ -8,6 +8,7 @@ module core_control_ldst
input insn_decode dec,
input logic issue,
mem_ready,
+ mem_ex_fail,
input word rd_value_b,
q_alu,
q_shifter,
@@ -23,6 +24,7 @@ module core_control_ldst
mem_offset,
output logic mem_start,
mem_write,
+ mem_ex_lock,
mem_user,
pop_valid,
ldst,
@@ -43,6 +45,9 @@ module core_control_ldst
assign ldst_next = !cycle.transfer || mem_ready;
assign mem_data_wr = q_shifter;
+ //TODO
+ assign mem_ex_lock = 0;
+
core_control_ldst_pop pop
(
.regs(mem_regs),
diff --git a/rtl/core/core.sv b/rtl/core/core.sv
index 3703fe4..3b87298 100644
--- a/rtl/core/core.sv
+++ b/rtl/core/core.sv
@@ -13,15 +13,17 @@ module core
output word avl_address,
output logic avl_read,
avl_write,
+ avl_lock,
input word avl_readdata,
output word avl_writedata,
input logic avl_waitrequest,
+ input logic[1:0] avl_response,
output logic[3:0] avl_byteenable,
input logic avl_irq
);
- logic ready, write, start;
+ logic ex_fail, ex_lock, start, ready, write;
logic[3:0] data_be;
logic[29:0] addr;
@@ -45,10 +47,13 @@ module core
.bus_ready(ready),
.bus_write(write),
.bus_start(start),
+ .bus_ex_fail(ex_fail),
+ .bus_ex_lock(ex_lock),
.*
);
assign data_rd = avl_readdata;
+ assign ex_fail = |avl_response;
always_comb
unique case(state)
@@ -66,6 +71,7 @@ module core
*/
if(!rst_n) begin
state <= IDLE;
+ avl_lock <= 0;
avl_read <= 0;
avl_write <= 0;
avl_address <= 0;
@@ -73,6 +79,7 @@ module core
avl_byteenable <= 0;
end else if((state == IDLE || !avl_waitrequest) && start) begin
state <= WAIT;
+ avl_lock <= ex_lock;
avl_read <= ~write;
avl_write <= write;
avl_address <= {addr, 2'b00};
diff --git a/rtl/core/mmu/arbiter.sv b/rtl/core/mmu/arbiter.sv
index 5a75ddf..b0da7c8 100644
--- a/rtl/core/mmu/arbiter.sv
+++ b/rtl/core/mmu/arbiter.sv
@@ -4,6 +4,7 @@ module core_mmu_arbiter
rst_n,
input logic bus_ready,
+ bus_ex_fail,
input word bus_data_rd,
data_data_wr,
input ptr insn_addr,
@@ -11,6 +12,7 @@ module core_mmu_arbiter
input logic insn_start,
data_start,
data_write,
+ data_ex_lock,
input logic[3:0] data_data_be,
output word bus_data_wr,
@@ -18,8 +20,10 @@ module core_mmu_arbiter
output ptr bus_addr,
output logic bus_start,
bus_write,
+ bus_ex_lock,
insn_ready,
data_ready,
+ data_ex_fail,
output word insn_data_rd,
data_data_rd
);
@@ -32,9 +36,10 @@ module core_mmu_arbiter
ptr hold_addr;
word hold_data_wr;
- logic active, hold_start, hold_write, hold_issue, hold_free, transition;
+ logic active, hold_ex_lock, hold_start, hold_write, hold_issue, hold_free, transition;
logic[3:0] hold_data_be;
+ assign data_ex_fail = bus_ex_fail;
assign insn_data_rd = bus_data_rd;
assign data_data_rd = bus_data_rd;
@@ -66,6 +71,7 @@ module core_mmu_arbiter
bus_write = 0;
bus_start = insn_start;
bus_data_be = 4'b1111;
+ bus_ex_lock = 0;
end
DATA: begin
@@ -73,6 +79,7 @@ module core_mmu_arbiter
bus_write = data_write;
bus_start = data_start;
bus_data_be = data_data_be;
+ bus_ex_lock = data_ex_lock;
end
endcase
@@ -82,6 +89,7 @@ module core_mmu_arbiter
bus_start = 1;
bus_data_wr = hold_data_wr;
bus_data_be = hold_data_be;
+ bus_ex_lock = hold_ex_lock;
end
end
@@ -95,6 +103,7 @@ module core_mmu_arbiter
hold_write <= 0;
hold_data_wr <= 0;
hold_data_be <= 0;
+ hold_ex_lock <= 0;
end else begin
master <= next_master;
active <= bus_start || (active && !bus_ready);
@@ -107,6 +116,7 @@ module core_mmu_arbiter
hold_write <= data_write;
hold_data_wr <= data_data_wr;
hold_data_be <= data_data_be;
+ hold_ex_lock <= data_ex_lock;
end
DATA: begin
@@ -114,6 +124,7 @@ module core_mmu_arbiter
hold_start <= insn_start;
hold_write <= 0;
hold_data_be <= 4'b1111;
+ hold_ex_lock <= 0;
end
endcase
end
diff --git a/rtl/core/mmu/mmu.sv b/rtl/core/mmu/mmu.sv
index b6c3668..22dfc3b 100644
--- a/rtl/core/mmu/mmu.sv
+++ b/rtl/core/mmu/mmu.sv
@@ -12,6 +12,7 @@ module core_mmu
input word mmu_dac,
input logic bus_ready,
+ bus_ex_fail,
input word bus_data_rd,
data_data_wr,
input ptr insn_addr,
@@ -19,6 +20,7 @@ module core_mmu
input logic insn_start,
data_start,
data_write,
+ data_ex_lock,
data_user,
input logic[3:0] data_data_be,
@@ -27,10 +29,12 @@ module core_mmu
output ptr bus_addr,
output logic bus_start,
bus_write,
+ bus_ex_lock,
insn_ready,
insn_fault,
data_ready,
data_fault,
+ data_ex_fail,
output word insn_data_rd,
data_data_rd,
@@ -43,9 +47,11 @@ module core_mmu
ptr iphys_addr, dphys_addr;
word iphys_data_rd, dphys_data_rd, dphys_data_wr;
- logic iphys_start, dphys_start, iphys_ready, dphys_ready, dphys_write;
logic[3:0] dphys_data_be;
+ logic iphys_start, dphys_start, iphys_ready, dphys_ready, dphys_write,
+ dphys_ex_fail, dphys_ex_lock;
+
assign fault_register = data_fault;
core_mmu_pagewalk iwalk
@@ -54,10 +60,13 @@ module core_mmu
.core_start(insn_start),
.core_write(0),
.core_ready(insn_ready),
- .core_fault(insn_fault),
.core_data_wr(0),
.core_data_be(0),
.core_data_rd(insn_data_rd),
+ .core_ex_fail(),
+ .core_ex_lock(0),
+
+ .core_fault(insn_fault),
.core_fault_addr(),
.core_fault_page(),
.core_fault_type(),
@@ -70,6 +79,8 @@ module core_mmu
.bus_data_wr(),
.bus_data_be(),
.bus_data_rd(iphys_data_rd),
+ .bus_ex_fail(0),
+ .bus_ex_lock(),
.*
);
@@ -80,10 +91,13 @@ module core_mmu
.core_start(data_start),
.core_write(data_write),
.core_ready(data_ready),
- .core_fault(data_fault),
.core_data_wr(data_data_wr),
.core_data_be(data_data_be),
.core_data_rd(data_data_rd),
+ .core_ex_fail(data_ex_fail),
+ .core_ex_lock(data_ex_lock),
+
+ .core_fault(data_fault),
.core_fault_addr(fault_addr),
.core_fault_page(fault_page),
.core_fault_type(fault_type),
@@ -96,6 +110,8 @@ module core_mmu
.bus_data_wr(dphys_data_wr),
.bus_data_be(dphys_data_be),
.bus_data_rd(dphys_data_rd),
+ .bus_ex_fail(dphys_ex_fail),
+ .bus_ex_lock(dphys_ex_lock),
.privileged(privileged && !data_user),
.*
@@ -115,6 +131,8 @@ module core_mmu
.data_data_wr(dphys_data_wr),
.data_data_be(dphys_data_be),
.data_data_rd(dphys_data_rd),
+ .data_ex_fail(dphys_ex_fail),
+ .data_ex_lock(dphys_ex_lock),
.*
);
diff --git a/rtl/core/mmu/pagewalk.sv b/rtl/core/mmu/pagewalk.sv
index 13da8c9..70c932c 100644
--- a/rtl/core/mmu/pagewalk.sv
+++ b/rtl/core/mmu/pagewalk.sv
@@ -12,6 +12,7 @@ module core_mmu_pagewalk
input word mmu_dac,
input logic bus_ready,
+ bus_ex_fail,
input word bus_data_rd,
input ptr core_addr,
@@ -19,15 +20,18 @@ module core_mmu_pagewalk
input logic[3:0] core_data_be,
input logic core_start,
core_write,
+ core_ex_lock,
output ptr bus_addr,
output word bus_data_wr,
output logic[3:0] bus_data_be,
output logic bus_start,
bus_write,
+ bus_ex_lock,
output word core_data_rd,
output logic core_ready,
+ core_ex_fail,
core_fault,
core_fault_page,
output ptr core_fault_addr,
@@ -81,7 +85,7 @@ module core_mmu_pagewalk
ptr target;
word hold_data;
- logic hold_write;
+ logic hold_write, hold_ex_lock;
logic[3:0] hold_be;
always_comb begin
@@ -138,15 +142,18 @@ module core_mmu_pagewalk
hold_be <= 0;
hold_data <= 0;
hold_write <= 0;
+ hold_ex_lock <= 0;
bus_addr <= 0;
bus_start <= 0;
bus_write <= 0;
+ bus_ex_lock <= 0;
bus_data_be <= 0;
bus_data_wr <= 0;
core_ready <= 0;
core_fault <= 0;
+ core_ex_fail <= 0;
core_data_rd <= 0;
core_fault_page <= 0;
core_fault_addr <= 0;
@@ -171,14 +178,17 @@ module core_mmu_pagewalk
hold_be <= core_data_be;
hold_data <= core_data_wr;
hold_write <= core_write;
+ hold_ex_lock <= core_ex_lock;
state <= L1;
bus_addr <= {mmu_ttbr, core_addr `MMU_L1_INDEX};
bus_write <= 0;
+ bus_ex_lock <= 0;
end else begin
state <= DATA;
bus_addr <= core_addr;
bus_write <= core_write;
+ bus_ex_lock <= core_ex_lock;
bus_data_wr <= core_data_wr;
bus_data_be <= core_data_be;
end
@@ -198,6 +208,7 @@ module core_mmu_pagewalk
state <= DATA;
bus_addr <= {section.base, target `MMU_SECTION_INDEX};
bus_write <= hold_write;
+ bus_ex_lock <= hold_ex_lock;
bus_data_wr <= hold_data;
bus_data_be <= hold_be;
end
@@ -211,6 +222,7 @@ module core_mmu_pagewalk
state <= DATA;
bus_write <= hold_write;
+ bus_ex_lock <= hold_ex_lock;
bus_data_wr <= hold_data;
bus_data_be <= hold_be;
@@ -229,6 +241,7 @@ module core_mmu_pagewalk
if(bus_ready) begin
state <= IDLE;
core_ready <= 1;
+ core_ex_fail <= bus_ex_fail;
core_data_rd <= bus_data_rd;
end