summaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2023-10-28 02:29:46 -0600
committerAlejandro Soto <alejandro@34project.org>2023-10-28 02:29:46 -0600
commit98d493f9c80f356cdbc2669150d772e451c3b80e (patch)
tree320f7c6b86ea5be5d07f848ec450663e9319de0b /rtl
parent7c5974f80f2b549a45721053037e877bc6bda438 (diff)
platform: implement support for disabling CPUs
Diffstat (limited to 'rtl')
-rw-r--r--rtl/cache/cache.sv181
-rw-r--r--rtl/cache/offsets.sv10
-rw-r--r--rtl/cache/routing.sv3
-rw-r--r--rtl/config.sv7
-rw-r--r--rtl/core/bus_master.sv74
-rw-r--r--rtl/core/core.sv99
6 files changed, 228 insertions, 146 deletions
diff --git a/rtl/cache/cache.sv b/rtl/cache/cache.sv
index 3cd71ee..463252d 100644
--- a/rtl/cache/cache.sv
+++ b/rtl/cache/cache.sv
@@ -1,15 +1,16 @@
`include "cache/defs.sv"
+`include "config.sv"
module cache
-#(parameter TOKEN_AT_RESET=0)
+#(parameter ID=0)
(
input logic clk,
- rst_n,
+ rst_n,
input ptr core_address,
input logic core_read,
- core_write,
- core_lock,
+ core_write,
+ core_lock,
input word core_writedata,
input word_be core_byteenable,
output logic core_waitrequest,
@@ -18,7 +19,7 @@ module cache
input logic[2:0] dbg_address,
input logic dbg_read,
- dbg_write,
+ dbg_write,
input word dbg_writedata,
output logic dbg_waitrequest,
output word dbg_readdata,
@@ -27,7 +28,7 @@ module cache
input line mem_readdata,
output word mem_address,
output logic mem_read,
- mem_write,
+ mem_write,
output line mem_writedata,
output line_be mem_byteenable,
@@ -46,59 +47,14 @@ module cache
output logic out_token_valid
);
- logic write_data, write_state;
- line data_wr, data_rd;
- addr_tag tag_wr, tag_rd;
- line_state state_wr, state_rd;
- addr_index index_rd, index_wr;
-
- cache_sram sram
- (
- .*
- );
-
- logic cache_core_waitrequest, debug_ready, send, send_read, send_inval,
- set_reply, lock_line, unlock_line, mem_begin, writeback;
-
- cache_control control
- (
- .core_read(cache_core_read),
- .core_write(cache_core_write),
- .core_waitrequest(cache_core_waitrequest),
-
- .*
- );
-
+ line cache_mem_writedata, data_rd;
word cache_mem_address;
- line cache_mem_writedata;
- logic cache_mem_waitrequest, cache_mem_read, cache_mem_write,
- mem_end, mem_read_end, mem_wait;
-
- addr_tag mem_tag;
- addr_index mem_index;
-
- cache_mem mem
- (
- .mem_waitrequest(cache_mem_waitrequest),
- .mem_address(cache_mem_address),
- .mem_writedata(cache_mem_writedata),
- .mem_read(cache_mem_read),
- .mem_write(cache_mem_write),
-
- .*
- );
-
- logic locked, may_send;
-
- cache_token #(.TOKEN_AT_RESET(TOKEN_AT_RESET)) token
- (
- .*
- );
+ logic cache_core_waitrequest, cache_mem_waitrequest, cache_mem_read, cache_mem_write;
- logic in_hold_valid, last_hop, out_stall;
- ring_req in_hold;
+ line core_writedata_line, core_data_wr;
+ line_be core_byteenable_line;
- cache_ring ring
+ cache_offsets offsets
(
.*
);
@@ -114,27 +70,96 @@ module cache
.*
);
- line core_writedata_line, core_data_wr;
- line_be core_byteenable_line;
-
- cache_offsets offsets
- (
- .*
- );
-
- line monitor_update;
- logic monitor_acquire, monitor_commit, monitor_fail, monitor_release;
-
- cache_monitor monitor
- (
- .*
- );
-
- addr_index debug_index;
-
- cache_debug debug
- (
- .*
- );
+ generate
+ if (ID < `CONFIG_CPUS && `CONFIG_CACHE) begin: enable
+ logic write_data, write_state;
+ line data_wr;
+ addr_tag tag_wr, tag_rd;
+ line_state state_wr, state_rd;
+ addr_index index_rd, index_wr;
+
+ cache_sram sram
+ (
+ .*
+ );
+
+ logic debug_ready, send, send_read, send_inval, set_reply, lock_line, unlock_line, mem_begin, writeback;
+
+ cache_control control
+ (
+ .core_read(cache_core_read),
+ .core_write(cache_core_write),
+ .core_waitrequest(cache_core_waitrequest),
+
+ .*
+ );
+
+ logic mem_end, mem_read_end, mem_wait;
+
+ addr_tag mem_tag;
+ addr_index mem_index;
+
+ cache_mem mem
+ (
+ .mem_waitrequest(cache_mem_waitrequest),
+ .mem_address(cache_mem_address),
+ .mem_writedata(cache_mem_writedata),
+ .mem_read(cache_mem_read),
+ .mem_write(cache_mem_write),
+
+ .*
+ );
+
+ logic locked, may_send;
+
+ cache_token #(.TOKEN_AT_RESET(ID == 0)) token
+ (
+ .*
+ );
+
+ logic in_hold_valid, last_hop, out_stall;
+ ring_req in_hold;
+
+ cache_ring ring
+ (
+ .*
+ );
+
+ line monitor_update;
+ logic monitor_acquire, monitor_commit, monitor_fail, monitor_release;
+
+ cache_monitor monitor
+ (
+ .*
+ );
+
+ addr_index debug_index;
+
+ cache_debug debug
+ (
+ .*
+ );
+ end else begin
+ assign dbg_waitrequest = 0;
+
+ assign cache_mem_read = 0;
+ assign cache_mem_write = 0;
+ assign cache_core_waitrequest = 0;
+
+ assign in_data_ready = out_data_ready;
+
+ ring_req null_fwd;
+ assign out_data = null_fwd;
+ assign out_data_valid = in_data_valid;
+
+ always_comb begin
+ null_fwd = in_data;
+ null_fwd.ttl = in_data.ttl - 1;
+ end
+
+ assign out_token = in_token;
+ assign out_token_valid = in_token_valid;
+ end
+ endgenerate
endmodule
diff --git a/rtl/cache/offsets.sv b/rtl/cache/offsets.sv
index 4a95e6a..7769394 100644
--- a/rtl/cache/offsets.sv
+++ b/rtl/cache/offsets.sv
@@ -2,8 +2,8 @@
module cache_offsets
(
- input addr_offset core_offset, // El offset es un input pero no
- // un output porque se mapea
+ input addr_offset core_offset, // El offset es un input pero no
+ // un output porque se mapea
input word_be core_byteenable,
input word core_writedata,
input line core_readdata_line,
@@ -11,9 +11,9 @@ module cache_offsets
output line core_data_wr,
core_writedata_line,
- output word core_readdata, // Readdata pasa de ser una line
- // en el input a una word por el
- // offset
+ output word core_readdata, // Readdata pasa de ser una line
+ // en el input a una word por el
+ // offset
output line_be core_byteenable_line
);
diff --git a/rtl/cache/routing.sv b/rtl/cache/routing.sv
index 4119a7f..a0c4347 100644
--- a/rtl/cache/routing.sv
+++ b/rtl/cache/routing.sv
@@ -1,4 +1,5 @@
`include "cache/defs.sv"
+`include "config.sv"
module cache_routing
(
@@ -63,7 +64,7 @@ module cache_routing
* Entonces si los bits de IO son distintos de 0, se sabe que no es
* una dirección cached
*/
- assign cached = io == `IO_CACHED;
+ assign cached = io == `IO_CACHED && `CONFIG_CACHE;
// Se afirma si cache quiere hacer un read o write de memoria
assign cache_mem = cache_mem_read || cache_mem_write;
diff --git a/rtl/config.sv b/rtl/config.sv
new file mode 100644
index 0000000..6353902
--- /dev/null
+++ b/rtl/config.sv
@@ -0,0 +1,7 @@
+`ifndef CONFIG_SV
+`define CONFIG_SV
+
+`define CONFIG_CPUS 4
+`define CONFIG_CACHE 1
+
+`endif
diff --git a/rtl/core/bus_master.sv b/rtl/core/bus_master.sv
new file mode 100644
index 0000000..39c4893
--- /dev/null
+++ b/rtl/core/bus_master.sv
@@ -0,0 +1,74 @@
+`include "core/uarch.sv"
+
+module bus_master
+(
+ input logic clk,
+ rst_n,
+
+ 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 start,
+ write,
+ ex_lock,
+ input ptr addr,
+ input logic[3:0] data_be,
+ input word data_wr,
+ output logic ready,
+ ex_fail,
+ output word data_rd
+);
+
+ enum int unsigned
+ {
+ IDLE,
+ WAIT
+ } state;
+
+ assign data_rd = avl_readdata;
+ assign ex_fail = |avl_response;
+
+ always_comb
+ unique case (state)
+ IDLE: ready = 0;
+ WAIT: ready = !avl_waitrequest;
+ endcase
+
+ always_ff @(posedge clk or negedge rst_n)
+ /* P. 16:
+ * A host must make no assumption about the assertion state of
+ * waitrequest when the host is idle: waitrequest may be high or
+ * low, depending on system properties. When waitrequest is asserted,
+ * host control signals to the agent must remain constant except for
+ * beginbursttransfer.
+ */
+ if(!rst_n) begin
+ state <= IDLE;
+ avl_lock <= 0;
+ avl_read <= 0;
+ avl_write <= 0;
+ avl_address <= 0;
+ avl_writedata <= 0;
+ 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};
+ avl_writedata <= data_wr;
+ avl_byteenable <= write ? data_be : 4'b1111;
+ end else if(state == WAIT && !avl_waitrequest) begin
+ state <= IDLE;
+ avl_read <= 0;
+ avl_write <= 0;
+ end
+
+endmodule
diff --git a/rtl/core/core.sv b/rtl/core/core.sv
index 3b87298..ce51a71 100644
--- a/rtl/core/core.sv
+++ b/rtl/core/core.sv
@@ -1,6 +1,8 @@
`include "core/uarch.sv"
+`include "config.sv"
module core
+#(parameter ID=0)
(
input logic clk,
rst_n,
@@ -23,72 +25,45 @@ module core
input logic avl_irq
);
- logic ex_fail, ex_lock, start, ready, write;
+ generate
+ if (ID < `CONFIG_CPUS) begin: enable
+ ptr addr;
+ word data_wr;
+ logic start, write;
+ logic[3:0] data_be;
- logic[3:0] data_be;
- logic[29:0] addr;
- logic[31:0] data_rd, data_wr;
+ arm810 cpu
+ (
+ .irq(avl_irq),
+ .halt(cpu_halt),
+ .halted(cpu_halted),
+ .bus_addr(addr),
+ .bus_data_rd(data_rd),
+ .bus_data_wr(data_wr),
+ .bus_data_be(data_be),
+ .bus_ready(ready),
+ .bus_write(write),
+ .bus_start(start),
+ .bus_ex_fail(ex_fail),
+ .bus_ex_lock(ex_lock),
+ .*
+ );
- enum int unsigned
- {
- IDLE,
- WAIT
- } state;
+ word data_rd;
+ logic ex_fail, ex_lock, ready;
- arm810 cpu
- (
- .irq(avl_irq),
- .halt(cpu_halt),
- .halted(cpu_halted),
- .bus_addr(addr),
- .bus_data_rd(data_rd),
- .bus_data_wr(data_wr),
- .bus_data_be(data_be),
- .bus_ready(ready),
- .bus_write(write),
- .bus_start(start),
- .bus_ex_fail(ex_fail),
- .bus_ex_lock(ex_lock),
- .*
- );
+ bus_master master
+ (
+ .*
+ );
+ end else begin
+ assign cpu_halted = 1;
+ assign breakpoint = 0;
- assign data_rd = avl_readdata;
- assign ex_fail = |avl_response;
-
- always_comb
- unique case(state)
- IDLE: ready = 0;
- WAIT: ready = !avl_waitrequest;
- endcase
-
- always_ff @(posedge clk or negedge rst_n)
- /* P. 16:
- * A host must make no assumption about the assertion state of
- * waitrequest when the host is idle: waitrequest may be high or
- * low, depending on system properties. When waitrequest is asserted,
- * host control signals to the agent must remain constant except for
- * beginbursttransfer.
- */
- if(!rst_n) begin
- state <= IDLE;
- avl_lock <= 0;
- avl_read <= 0;
- avl_write <= 0;
- avl_address <= 0;
- avl_writedata <= 0;
- 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};
- avl_writedata <= data_wr;
- avl_byteenable <= write ? data_be : 4'b1111;
- end else if(state == WAIT && !avl_waitrequest) begin
- state <= IDLE;
- avl_read <= 0;
- avl_write <= 0;
+ assign avl_lock = 0;
+ assign avl_read = 0;
+ assign avl_write = 0;
end
+ endgenerate
endmodule