diff options
Diffstat (limited to 'rtl')
| -rw-r--r-- | rtl/cache/cache.sv | 2 | ||||
| -rw-r--r-- | rtl/cache/cache_control.sv | 45 | ||||
| -rw-r--r-- | rtl/cache/defs.sv | 4 | ||||
| -rw-r--r-- | rtl/core/arm810.sv | 11 | ||||
| -rw-r--r-- | rtl/core/control/control.sv | 2 | ||||
| -rw-r--r-- | rtl/core/control/ldst/ldst.sv | 5 | ||||
| -rw-r--r-- | rtl/core/core.sv | 9 | ||||
| -rw-r--r-- | rtl/core/mmu/arbiter.sv | 13 | ||||
| -rw-r--r-- | rtl/core/mmu/mmu.sv | 24 | ||||
| -rw-r--r-- | rtl/core/mmu/pagewalk.sv | 15 |
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 |
