diff options
| author | Alejandro Soto <alejandro@34project.org> | 2023-10-28 02:29:46 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2023-10-28 02:29:46 -0600 |
| commit | 98d493f9c80f356cdbc2669150d772e451c3b80e (patch) | |
| tree | 320f7c6b86ea5be5d07f848ec450663e9319de0b | |
| parent | 7c5974f80f2b549a45721053037e877bc6bda438 (diff) | |
platform: implement support for disabling CPUs
| -rw-r--r-- | cache_hw.tcl | 16 | ||||
| -rw-r--r-- | core_hw.tcl | 9 | ||||
| -rw-r--r-- | platform.qsys | 12 | ||||
| -rw-r--r-- | rtl/cache/cache.sv | 181 | ||||
| -rw-r--r-- | rtl/cache/offsets.sv | 10 | ||||
| -rw-r--r-- | rtl/cache/routing.sv | 3 | ||||
| -rw-r--r-- | rtl/config.sv | 7 | ||||
| -rw-r--r-- | rtl/core/bus_master.sv | 74 | ||||
| -rw-r--r-- | rtl/core/core.sv | 99 | ||||
| -rw-r--r-- | tb/top/conspiracion.cpp | 40 | ||||
| -rw-r--r-- | tb/top/conspiracion/platform.sv | 16 |
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), |
