summaryrefslogtreecommitdiff
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
parent7c5974f80f2b549a45721053037e877bc6bda438 (diff)
platform: implement support for disabling CPUs
-rw-r--r--cache_hw.tcl16
-rw-r--r--core_hw.tcl9
-rw-r--r--platform.qsys12
-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
-rw-r--r--tb/top/conspiracion.cpp40
-rw-r--r--tb/top/conspiracion/platform.sv16
11 files changed, 270 insertions, 197 deletions
diff --git a/cache_hw.tcl b/cache_hw.tcl
index 269a368..712cf67 100644
--- a/cache_hw.tcl
+++ b/cache_hw.tcl
@@ -55,14 +55,14 @@ add_fileset_file cache_debug.sv SYSTEM_VERILOG PATH rtl/cache/cache_debug.sv
#
# parameters
#
-add_parameter TOKEN_AT_RESET INTEGER 0
-set_parameter_property TOKEN_AT_RESET DEFAULT_VALUE 0
-set_parameter_property TOKEN_AT_RESET DISPLAY_NAME TOKEN_AT_RESET
-set_parameter_property TOKEN_AT_RESET TYPE INTEGER
-set_parameter_property TOKEN_AT_RESET UNITS None
-set_parameter_property TOKEN_AT_RESET ALLOWED_RANGES -2147483648:2147483647
-set_parameter_property TOKEN_AT_RESET AFFECTS_GENERATION false
-set_parameter_property TOKEN_AT_RESET HDL_PARAMETER true
+add_parameter ID INTEGER 0
+set_parameter_property ID DEFAULT_VALUE 0
+set_parameter_property ID DISPLAY_NAME ID
+set_parameter_property ID TYPE INTEGER
+set_parameter_property ID UNITS None
+set_parameter_property ID ALLOWED_RANGES 0:3
+set_parameter_property ID AFFECTS_GENERATION false
+set_parameter_property ID HDL_PARAMETER true
#
diff --git a/core_hw.tcl b/core_hw.tcl
index 0bdd457..0b0a2da 100644
--- a/core_hw.tcl
+++ b/core_hw.tcl
@@ -40,6 +40,7 @@ set_fileset_property QUARTUS_SYNTH TOP_LEVEL core
set_fileset_property QUARTUS_SYNTH ENABLE_RELATIVE_INCLUDE_PATHS false
set_fileset_property QUARTUS_SYNTH ENABLE_FILE_OVERWRITE_MODE false
add_fileset_file core.sv SYSTEM_VERILOG PATH rtl/core/core.sv TOP_LEVEL_FILE
+add_fileset_file bus_master.sv SYSTEM_VERILOG PATH rtl/core/bus_master.sv
add_fileset_file arm810.sv SYSTEM_VERILOG PATH rtl/core/arm810.sv
add_fileset_file mul.sv SYSTEM_VERILOG PATH rtl/core/mul.sv
add_fileset_file psr.sv SYSTEM_VERILOG PATH rtl/core/psr.sv
@@ -111,6 +112,14 @@ add_fileset_file exclusive.sv SYSTEM_VERILOG PATH rtl/core/decode/ldst/exclusive
#
# parameters
#
+add_parameter ID INTEGER 0
+set_parameter_property ID DEFAULT_VALUE 0
+set_parameter_property ID DISPLAY_NAME ID
+set_parameter_property ID TYPE INTEGER
+set_parameter_property ID UNITS None
+set_parameter_property ID ALLOWED_RANGES 0:3
+set_parameter_property ID AFFECTS_GENERATION false
+set_parameter_property ID HDL_PARAMETER true
#
diff --git a/platform.qsys b/platform.qsys
index 6e6e45c..b07ad9b 100644
--- a/platform.qsys
+++ b/platform.qsys
@@ -392,16 +392,16 @@
<parameter name="width" value="8" />
</module>
<module name="cache_0" kind="cache" version="1.0" enabled="1">
- <parameter name="TOKEN_AT_RESET" value="0" />
+ <parameter name="ID" value="0" />
</module>
<module name="cache_1" kind="cache" version="1.0" enabled="1">
- <parameter name="TOKEN_AT_RESET" value="0" />
+ <parameter name="ID" value="1" />
</module>
<module name="cache_2" kind="cache" version="1.0" enabled="1">
- <parameter name="TOKEN_AT_RESET" value="0" />
+ <parameter name="ID" value="2" />
</module>
<module name="cache_3" kind="cache" version="1.0" enabled="1">
- <parameter name="TOKEN_AT_RESET" value="1" />
+ <parameter name="ID" value="3" />
</module>
<module name="clk_0" kind="clock_source" version="20.1" enabled="1">
<parameter name="clockFrequency" value="50000000" />
@@ -411,15 +411,19 @@
</module>
<module name="cpu_0" kind="core" version="1.0" enabled="1">
<parameter name="AUTO_INTERRUPT_RECEIVER_INTERRUPTS_USED" value="1" />
+ <parameter name="ID" value="0" />
</module>
<module name="cpu_1" kind="core" version="1.0" enabled="1">
<parameter name="AUTO_INTERRUPT_RECEIVER_INTERRUPTS_USED" value="0" />
+ <parameter name="ID" value="1" />
</module>
<module name="cpu_2" kind="core" version="1.0" enabled="1">
<parameter name="AUTO_INTERRUPT_RECEIVER_INTERRUPTS_USED" value="0" />
+ <parameter name="ID" value="2" />
</module>
<module name="cpu_3" kind="core" version="1.0" enabled="1">
<parameter name="AUTO_INTERRUPT_RECEIVER_INTERRUPTS_USED" value="0" />
+ <parameter name="ID" value="3" />
</module>
<module name="gfx_0" kind="gfx" version="1.0" enabled="1" />
<module name="hps_0" kind="altera_hps" version="20.1" enabled="1">
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
diff --git a/tb/top/conspiracion.cpp b/tb/top/conspiracion.cpp
index d8f5f62..e1f5f78 100644
--- a/tb/top/conspiracion.cpp
+++ b/tb/top/conspiracion.cpp
@@ -16,29 +16,7 @@
#include <verilated_fst_c.h>
#endif
-#include "Vtop.h"
-#include "Vtop_arm810.h"
-#include "Vtop_conspiracion.h"
-#include "Vtop_platform.h"
-#include "Vtop_sim_slave.h"
-#include "Vtop_vga_domain.h"
-#include "Vtop_core.h"
-#include "Vtop_core_control.h"
-#include "Vtop_core_control_issue.h"
-#include "Vtop_core_cp15_domain.h"
-#include "Vtop_core_cp15_far.h"
-#include "Vtop_core_cp15_fsr.h"
-#include "Vtop_core_cp15_syscfg.h"
-#include "Vtop_core_cp15_ttbr.h"
-#include "Vtop_core_cp15.h"
-#include "Vtop_core_fetch.h"
-#include "Vtop_core_mmu.h"
-#include "Vtop_core_psr.h"
-#include "Vtop_core_regs.h"
-#include "Vtop_core_reg_file.h"
-#include "Vtop_cache.h"
-#include "Vtop_cache__T1.h"
-#include "Vtop_cache_sram.h"
+#include "Vtop__Syms.h"
#include "args.hxx"
@@ -414,17 +392,17 @@ int main(int argc, char **argv)
}
Vtop_arm810 *const cores[] = {
- plat.cpu_0->cpu,
- plat.cpu_1->cpu,
- plat.cpu_2->cpu,
- plat.cpu_3->cpu
+ plat.cpu_0->enable__DOT__cpu,
+ plat.cpu_1->enable__DOT__cpu,
+ plat.cpu_2->enable__DOT__cpu,
+ plat.cpu_3->enable__DOT__cpu
};
Vtop_cache_sram *const caches[] = {
- plat.cache_0->sram,
- plat.cache_1->sram,
- plat.cache_2->sram,
- plat.cache_3->sram
+ plat.cache_0->enable__DOT__sram,
+ plat.cache_1->enable__DOT__sram,
+ plat.cache_2->enable__DOT__sram,
+ plat.cache_3->enable__DOT__sram
};
for (const auto &init : init_regs) {
diff --git a/tb/top/conspiracion/platform.sv b/tb/top/conspiracion/platform.sv
index 054a302..9c6fb27 100644
--- a/tb/top/conspiracion/platform.sv
+++ b/tb/top/conspiracion/platform.sv
@@ -88,7 +88,7 @@ module platform
logic[1:0] cpu_0_response, cpu_1_response, cpu_2_response, cpu_3_response;
logic[3:0] cpu_0_byteenable, cpu_1_byteenable, cpu_2_byteenable, cpu_3_byteenable;
- core cpu_0
+ core #(.ID(0)) cpu_0
(
.step(step_0),
.breakpoint(breakpoint_0),
@@ -106,7 +106,7 @@ module platform
.*
);
- core cpu_1
+ core #(.ID(1)) cpu_1
(
.step(step_1),
.breakpoint(breakpoint_1),
@@ -125,7 +125,7 @@ module platform
.*
);
- core cpu_2
+ core #(.ID(2)) cpu_2
(
.step(step_2),
.breakpoint(breakpoint_2),
@@ -144,7 +144,7 @@ module platform
.*
);
- core cpu_3
+ core #(.ID(3)) cpu_3
(
.step(step_3),
.breakpoint(breakpoint_3),
@@ -177,7 +177,7 @@ module platform
out_0_ready, out_1_ready, out_2_ready, out_3_ready,
token_valid_0, token_valid_1, token_valid_2, token_valid_3;
- cache cache_0
+ cache #(.ID(0)) cache_0
(
.core_address(cpu_0_address[31:2]),
.core_read(cpu_0_read),
@@ -233,7 +233,7 @@ module platform
.*
);
- cache cache_1
+ cache #(.ID(1)) cache_1
(
.core_address(cpu_1_address[31:2]),
.core_read(cpu_1_read),
@@ -289,7 +289,7 @@ module platform
.*
);
- cache cache_2
+ cache #(.ID(2)) cache_2
(
.core_address(cpu_2_address[31:2]),
.core_read(cpu_2_read),
@@ -345,7 +345,7 @@ module platform
.*
);
- cache #(.TOKEN_AT_RESET(1)) cache_3
+ cache #(.ID(3)) cache_3
(
.core_address(cpu_3_address[31:2]),
.core_read(cpu_3_read),