Merge branch 'fpga_synthesis' of https://github.gatech.edu/casl/Vortex into fpga_synthesis
This commit is contained in:
9
Makefile
9
Makefile
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
all:
|
all:
|
||||||
$(MAKE) -C hw
|
$(MAKE) -C hw
|
||||||
$(MAKE) -C driver
|
$(MAKE) -C driver
|
||||||
$(MAKE) -C runtime
|
$(MAKE) -C runtime
|
||||||
$(MAKE) -C simX
|
$(MAKE) -C simX
|
||||||
@@ -19,7 +19,7 @@ DBG_PRINT_FLAGS = -DDBG_PRINT_CORE_ICACHE \
|
|||||||
MULTICORE += -DNUM_CLUSTERS=1 -DNUM_CORES=2
|
MULTICORE += -DNUM_CLUSTERS=1 -DNUM_CORES=2
|
||||||
|
|
||||||
#DEBUG=1
|
#DEBUG=1
|
||||||
#AFU=1
|
AFU=1
|
||||||
|
|
||||||
CFLAGS += -fPIC
|
CFLAGS += -fPIC
|
||||||
|
|
||||||
@@ -55,8 +55,8 @@ endif
|
|||||||
# AFU
|
# AFU
|
||||||
ifdef AFU
|
ifdef AFU
|
||||||
TOP = vortex_afu_sim
|
TOP = vortex_afu_sim
|
||||||
VL_FLAGS += -DNOPAE
|
VL_FLAGS += -DNOPAE -DSCOPE
|
||||||
CFLAGS += -DNOPAE
|
CFLAGS += -DNOPAE -DSCOPE
|
||||||
RTL_INCLUDE += -I../../hw/opae -I../../hw/opae/ccip
|
RTL_INCLUDE += -I../../hw/opae -I../../hw/opae/ccip
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,12 @@
|
|||||||
"clock-frequency-low": "auto",
|
"clock-frequency-low": "auto",
|
||||||
|
|
||||||
"mmio-csr-cmd": 10,
|
"mmio-csr-cmd": 10,
|
||||||
"mmio-csr-status": 12,
|
"mmio-csr-io-addr": 12,
|
||||||
"mmio-csr-io-addr": 14,
|
"mmio-csr-mem-addr": 14,
|
||||||
"mmio-csr-mem-addr": 16,
|
"mmio-csr-data-size": 16,
|
||||||
"mmio-csr-data-size": 18,
|
"mmio-csr-status": 18,
|
||||||
|
"mmio-csr-scope-delay": 20,
|
||||||
|
"mmio-csr-scope-data": 22,
|
||||||
|
|
||||||
"cmd-type-read": 1,
|
"cmd-type-read": 1,
|
||||||
"cmd-type-write": 2,
|
"cmd-type-write": 2,
|
||||||
|
|||||||
@@ -61,10 +61,13 @@ localparam CMD_TYPE_RUN = `AFU_IMAGE_CMD_TYPE_RUN;
|
|||||||
localparam CMD_TYPE_CLFLUSH = `AFU_IMAGE_CMD_TYPE_CLFLUSH;
|
localparam CMD_TYPE_CLFLUSH = `AFU_IMAGE_CMD_TYPE_CLFLUSH;
|
||||||
|
|
||||||
localparam MMIO_CSR_CMD = `AFU_IMAGE_MMIO_CSR_CMD;
|
localparam MMIO_CSR_CMD = `AFU_IMAGE_MMIO_CSR_CMD;
|
||||||
localparam MMIO_CSR_STATUS = `AFU_IMAGE_MMIO_CSR_STATUS;
|
|
||||||
localparam MMIO_CSR_IO_ADDR = `AFU_IMAGE_MMIO_CSR_IO_ADDR;
|
localparam MMIO_CSR_IO_ADDR = `AFU_IMAGE_MMIO_CSR_IO_ADDR;
|
||||||
localparam MMIO_CSR_MEM_ADDR = `AFU_IMAGE_MMIO_CSR_MEM_ADDR;
|
localparam MMIO_CSR_MEM_ADDR = `AFU_IMAGE_MMIO_CSR_MEM_ADDR;
|
||||||
localparam MMIO_CSR_DATA_SIZE = `AFU_IMAGE_MMIO_CSR_DATA_SIZE;
|
localparam MMIO_CSR_DATA_SIZE = `AFU_IMAGE_MMIO_CSR_DATA_SIZE;
|
||||||
|
localparam MMIO_CSR_STATUS = `AFU_IMAGE_MMIO_CSR_STATUS;
|
||||||
|
|
||||||
|
localparam MMIO_CSR_SCOPE_DELAY = `AFU_IMAGE_MMIO_CSR_SCOPE_DELAY;
|
||||||
|
localparam MMIO_CSR_SCOPE_DATA = `AFU_IMAGE_MMIO_CSR_SCOPE_DATA;
|
||||||
|
|
||||||
logic [127:0] afu_id = `AFU_ACCEL_UUID;
|
logic [127:0] afu_id = `AFU_ACCEL_UUID;
|
||||||
|
|
||||||
@@ -135,6 +138,11 @@ t_ccip_clAddr csr_io_addr;
|
|||||||
logic[DRAM_ADDR_WIDTH-1:0] csr_mem_addr;
|
logic[DRAM_ADDR_WIDTH-1:0] csr_mem_addr;
|
||||||
logic[DRAM_ADDR_WIDTH-1:0] csr_data_size;
|
logic[DRAM_ADDR_WIDTH-1:0] csr_data_size;
|
||||||
|
|
||||||
|
logic [63:0] csr_scope_delay;
|
||||||
|
logic [63:0] csr_scope_data;
|
||||||
|
logic csr_scope_read;
|
||||||
|
logic csr_scope_write;
|
||||||
|
|
||||||
// MMIO controller ////////////////////////////////////////////////////////////
|
// MMIO controller ////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
`IGNORE_WARNINGS_BEGIN
|
`IGNORE_WARNINGS_BEGIN
|
||||||
@@ -145,6 +153,10 @@ assign mmio_hdr = t_ccip_c0_ReqMmioHdr'(cp2af_sRxPort.c0.hdr);
|
|||||||
t_if_ccip_c2_Tx mmio_tx;
|
t_if_ccip_c2_Tx mmio_tx;
|
||||||
assign af2cp_sTxPort.c2 = mmio_tx;
|
assign af2cp_sTxPort.c2 = mmio_tx;
|
||||||
|
|
||||||
|
assign csr_scope_delay = 64'(cp2af_sRxPort.c0.data);
|
||||||
|
assign csr_scope_write = cp2af_sRxPort.c0.mmioWrValid && (MMIO_CSR_SCOPE_DELAY == mmio_hdr.address);
|
||||||
|
assign csr_scope_read = cp2af_sRxPort.c0.mmioRdValid && (MMIO_CSR_SCOPE_DATA == mmio_hdr.address);
|
||||||
|
|
||||||
always_ff @(posedge clk)
|
always_ff @(posedge clk)
|
||||||
begin
|
begin
|
||||||
if (SoftReset) begin
|
if (SoftReset) begin
|
||||||
@@ -158,7 +170,7 @@ begin
|
|||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
|
|
||||||
csr_cmd <= 0;
|
csr_cmd <= 0;
|
||||||
mmio_tx.mmioRdValid <= 0;
|
mmio_tx.mmioRdValid <= 0;
|
||||||
|
|
||||||
// serve MMIO write request
|
// serve MMIO write request
|
||||||
@@ -223,7 +235,13 @@ begin
|
|||||||
$display("%t: STATUS: state=%0d", $time, state);
|
$display("%t: STATUS: state=%0d", $time, state);
|
||||||
end
|
end
|
||||||
`endif
|
`endif
|
||||||
mmio_tx.data <= {60'b0, state};
|
mmio_tx.data <= 64'(state);
|
||||||
|
end
|
||||||
|
MMIO_CSR_SCOPE_DATA: begin
|
||||||
|
mmio_tx.data <= csr_scope_data;
|
||||||
|
`ifdef DBG_PRINT_OPAE
|
||||||
|
$display("%t: scope: data=%0d", $time, csr_scope_data);
|
||||||
|
`endif
|
||||||
end
|
end
|
||||||
default: mmio_tx.data <= 64'h0;
|
default: mmio_tx.data <= 64'h0;
|
||||||
endcase
|
endcase
|
||||||
@@ -768,11 +786,36 @@ begin
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// SCOPE //////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
`ifdef SCOPE
|
||||||
|
|
||||||
|
`SCOPE_SIGNALS_DECL()
|
||||||
|
|
||||||
|
VX_scope #(
|
||||||
|
.DATAW ($bits({`SCOPE_SIGNALS_LIST()})),
|
||||||
|
.BUSW (64),
|
||||||
|
.SIZE (1024)
|
||||||
|
) scope (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (SoftReset),
|
||||||
|
.start (vx_reset),
|
||||||
|
.data_in ({`SCOPE_SIGNALS_LIST()}),
|
||||||
|
.bus_in (csr_scope_delay),
|
||||||
|
.bus_out (csr_scope_data),
|
||||||
|
.bus_read (csr_scope_read),
|
||||||
|
.bus_write(csr_scope_write)
|
||||||
|
);
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
// Vortex binding /////////////////////////////////////////////////////////////
|
// Vortex binding /////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
assign cmd_run_done = !vx_busy;
|
assign cmd_run_done = !vx_busy;
|
||||||
|
|
||||||
Vortex_Socket #() vx_socket (
|
Vortex_Socket #() vx_socket (
|
||||||
|
`SCOPE_SIGNALS_ATTACH(),
|
||||||
|
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.reset (vx_reset),
|
.reset (vx_reset),
|
||||||
|
|
||||||
|
|||||||
@@ -7,42 +7,42 @@ module VX_dcache_io_arb (
|
|||||||
VX_cache_core_req_if core_req_if,
|
VX_cache_core_req_if core_req_if,
|
||||||
|
|
||||||
// Dcache request
|
// Dcache request
|
||||||
VX_cache_core_req_if dcache_core_req_if,
|
VX_cache_core_req_if core_dcache_req_if,
|
||||||
|
|
||||||
// I/O request
|
// I/O request
|
||||||
VX_cache_core_req_if io_core_req_if,
|
VX_cache_core_req_if core_io_req_if,
|
||||||
|
|
||||||
// Dcache response
|
// Dcache response
|
||||||
VX_cache_core_rsp_if dcache_core_rsp_if,
|
VX_cache_core_rsp_if core_dcache_rsp_if,
|
||||||
|
|
||||||
// I/O response
|
// I/O response
|
||||||
VX_cache_core_rsp_if io_core_rsp_if,
|
VX_cache_core_rsp_if core_io_rsp_if,
|
||||||
|
|
||||||
// Core response
|
// Core response
|
||||||
VX_cache_core_rsp_if core_rsp_if
|
VX_cache_core_rsp_if core_rsp_if
|
||||||
);
|
);
|
||||||
assign dcache_core_req_if.core_req_valid = core_req_if.core_req_valid & {`NUM_THREADS{~io_select}};
|
assign core_dcache_req_if.core_req_valid = core_req_if.core_req_valid & {`NUM_THREADS{~io_select}};
|
||||||
assign dcache_core_req_if.core_req_rw = core_req_if.core_req_rw;
|
assign core_dcache_req_if.core_req_rw = core_req_if.core_req_rw;
|
||||||
assign dcache_core_req_if.core_req_byteen= core_req_if.core_req_byteen;
|
assign core_dcache_req_if.core_req_byteen= core_req_if.core_req_byteen;
|
||||||
assign dcache_core_req_if.core_req_addr = core_req_if.core_req_addr;
|
assign core_dcache_req_if.core_req_addr = core_req_if.core_req_addr;
|
||||||
assign dcache_core_req_if.core_req_data = core_req_if.core_req_data;
|
assign core_dcache_req_if.core_req_data = core_req_if.core_req_data;
|
||||||
assign dcache_core_req_if.core_req_tag = core_req_if.core_req_tag;
|
assign core_dcache_req_if.core_req_tag = core_req_if.core_req_tag;
|
||||||
|
|
||||||
assign io_core_req_if.core_req_valid = core_req_if.core_req_valid & {`NUM_THREADS{io_select}};
|
assign core_io_req_if.core_req_valid = core_req_if.core_req_valid & {`NUM_THREADS{io_select}};
|
||||||
assign io_core_req_if.core_req_rw = core_req_if.core_req_rw;
|
assign core_io_req_if.core_req_rw = core_req_if.core_req_rw;
|
||||||
assign io_core_req_if.core_req_byteen= core_req_if.core_req_byteen;
|
assign core_io_req_if.core_req_byteen= core_req_if.core_req_byteen;
|
||||||
assign io_core_req_if.core_req_addr = core_req_if.core_req_addr;
|
assign core_io_req_if.core_req_addr = core_req_if.core_req_addr;
|
||||||
assign io_core_req_if.core_req_data = core_req_if.core_req_data;
|
assign core_io_req_if.core_req_data = core_req_if.core_req_data;
|
||||||
assign io_core_req_if.core_req_tag = core_req_if.core_req_tag;
|
assign core_io_req_if.core_req_tag = core_req_if.core_req_tag;
|
||||||
|
|
||||||
assign core_req_if.core_req_ready = io_select ? io_core_req_if.core_req_ready : dcache_core_req_if.core_req_ready;
|
assign core_req_if.core_req_ready = io_select ? core_io_req_if.core_req_ready : core_dcache_req_if.core_req_ready;
|
||||||
|
|
||||||
wire dcache_rsp_valid = (| dcache_core_rsp_if.core_rsp_valid);
|
wire dcache_rsp_valid = (| core_dcache_rsp_if.core_rsp_valid);
|
||||||
|
|
||||||
assign core_rsp_if.core_rsp_valid = dcache_rsp_valid ? dcache_core_rsp_if.core_rsp_valid : io_core_rsp_if.core_rsp_valid;
|
assign core_rsp_if.core_rsp_valid = dcache_rsp_valid ? core_dcache_rsp_if.core_rsp_valid : core_io_rsp_if.core_rsp_valid;
|
||||||
assign core_rsp_if.core_rsp_data = dcache_rsp_valid ? dcache_core_rsp_if.core_rsp_data : io_core_rsp_if.core_rsp_data;
|
assign core_rsp_if.core_rsp_data = dcache_rsp_valid ? core_dcache_rsp_if.core_rsp_data : core_io_rsp_if.core_rsp_data;
|
||||||
assign core_rsp_if.core_rsp_tag = dcache_rsp_valid ? dcache_core_rsp_if.core_rsp_tag : io_core_rsp_if.core_rsp_tag;
|
assign core_rsp_if.core_rsp_tag = dcache_rsp_valid ? core_dcache_rsp_if.core_rsp_tag : core_io_rsp_if.core_rsp_tag;
|
||||||
assign dcache_core_rsp_if.core_rsp_ready = core_rsp_if.core_rsp_ready;
|
assign core_dcache_rsp_if.core_rsp_ready = core_rsp_if.core_rsp_ready;
|
||||||
assign io_core_rsp_if.core_rsp_ready = core_rsp_if.core_rsp_ready && ~dcache_rsp_valid;
|
assign core_io_rsp_if.core_rsp_ready = core_rsp_if.core_rsp_ready && ~dcache_rsp_valid;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
@@ -280,5 +280,101 @@
|
|||||||
|
|
||||||
`define DRAM_TO_BYTE_ADDR(x) {x, (32-$bits(x))'(0)}
|
`define DRAM_TO_BYTE_ADDR(x) {x, (32-$bits(x))'(0)}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
`ifdef SCOPE
|
||||||
|
`define SCOPE_SIGNALS_LIST() \
|
||||||
|
scope_icache_req_valid, \
|
||||||
|
scope_icache_req_tag, \
|
||||||
|
scope_icache_req_ready, \
|
||||||
|
scope_icache_rsp_valid, \
|
||||||
|
scope_icache_rsp_tag, \
|
||||||
|
scope_icache_rsp_ready, \
|
||||||
|
scope_dcache_req_valid, \
|
||||||
|
scope_dcache_req_tag, \
|
||||||
|
scope_dcache_req_ready, \
|
||||||
|
scope_dcache_rsp_valid, \
|
||||||
|
scope_dcache_rsp_tag, \
|
||||||
|
scope_dcache_rsp_ready, \
|
||||||
|
scope_dram_req_valid, \
|
||||||
|
scope_dram_req_tag, \
|
||||||
|
scope_dram_req_ready, \
|
||||||
|
scope_dram_rsp_valid, \
|
||||||
|
scope_dram_rsp_tag, \
|
||||||
|
scope_dram_rsp_ready, \
|
||||||
|
scope_schedule_delay
|
||||||
|
|
||||||
|
`define SCOPE_SIGNALS_DECL() \
|
||||||
|
wire scope_icache_req_valid; \
|
||||||
|
wire [`DCORE_TAG_WIDTH-1:0] scope_icache_req_tag; \
|
||||||
|
wire scope_icache_req_ready; \
|
||||||
|
wire scope_icache_rsp_valid; \
|
||||||
|
wire [`DCORE_TAG_WIDTH-1:0] scope_icache_rsp_tag; \
|
||||||
|
wire scope_icache_rsp_ready; \
|
||||||
|
wire [`DNUM_REQUESTS-1:0] scope_dcache_req_valid; \
|
||||||
|
wire [`ICORE_TAG_WIDTH-1:0] scope_dcache_req_tag; \
|
||||||
|
wire scope_dcache_req_ready; \
|
||||||
|
wire [`DNUM_REQUESTS-1:0] scope_dcache_rsp_valid; \
|
||||||
|
wire [`ICORE_TAG_WIDTH-1:0] scope_dcache_rsp_tag; \
|
||||||
|
wire scope_dcache_rsp_ready; \
|
||||||
|
wire scope_dram_req_valid; \
|
||||||
|
wire [`VX_DRAM_TAG_WIDTH-1:0] scope_dram_req_tag; \
|
||||||
|
wire scope_dram_req_ready; \
|
||||||
|
wire scope_dram_rsp_valid; \
|
||||||
|
wire [`VX_DRAM_TAG_WIDTH-1:0] scope_dram_rsp_tag; \
|
||||||
|
wire scope_dram_rsp_ready; \
|
||||||
|
wire scope_schedule_delay;
|
||||||
|
|
||||||
|
`define SCOPE_SIGNALS_IO() \
|
||||||
|
/* verilator lint_off UNDRIVEN */ \
|
||||||
|
output wire scope_icache_req_valid, \
|
||||||
|
output wire [`DCORE_TAG_WIDTH-1:0] scope_icache_req_tag, \
|
||||||
|
output wire scope_icache_req_ready, \
|
||||||
|
output wire scope_icache_rsp_valid, \
|
||||||
|
output wire [`DCORE_TAG_WIDTH-1:0] scope_icache_rsp_tag, \
|
||||||
|
output wire scope_icache_rsp_ready, \
|
||||||
|
output wire [`DNUM_REQUESTS-1:0] scope_dcache_req_valid, \
|
||||||
|
output wire [`ICORE_TAG_WIDTH-1:0] scope_dcache_req_tag, \
|
||||||
|
output wire scope_dcache_req_ready, \
|
||||||
|
output wire [`DNUM_REQUESTS-1:0] scope_dcache_rsp_valid, \
|
||||||
|
output wire [`ICORE_TAG_WIDTH-1:0] scope_dcache_rsp_tag, \
|
||||||
|
output wire scope_dcache_rsp_ready, \
|
||||||
|
output wire scope_dram_req_valid, \
|
||||||
|
output wire [`VX_DRAM_TAG_WIDTH-1:0] scope_dram_req_tag, \
|
||||||
|
output wire scope_dram_req_ready, \
|
||||||
|
output wire scope_dram_rsp_valid, \
|
||||||
|
output wire [`VX_DRAM_TAG_WIDTH-1:0] scope_dram_rsp_tag, \
|
||||||
|
output wire scope_dram_rsp_ready, \
|
||||||
|
output wire scope_schedule_delay \
|
||||||
|
/* verilator lint_on UNDRIVEN */
|
||||||
|
|
||||||
|
`define SCOPE_SIGNALS_ATTACH() \
|
||||||
|
.scope_icache_req_valid (scope_icache_req_valid), \
|
||||||
|
.scope_icache_req_tag (scope_icache_req_tag), \
|
||||||
|
.scope_icache_req_ready (scope_icache_req_ready), \
|
||||||
|
.scope_icache_rsp_valid (scope_icache_rsp_valid), \
|
||||||
|
.scope_icache_rsp_tag (scope_icache_rsp_tag), \
|
||||||
|
.scope_icache_rsp_ready (scope_icache_rsp_ready), \
|
||||||
|
.scope_dcache_req_valid (scope_dcache_req_valid), \
|
||||||
|
.scope_dcache_req_tag (scope_dcache_req_tag), \
|
||||||
|
.scope_dcache_req_ready (scope_dcache_req_ready), \
|
||||||
|
.scope_dcache_rsp_valid (scope_dcache_rsp_valid), \
|
||||||
|
.scope_dcache_rsp_tag (scope_dcache_rsp_tag), \
|
||||||
|
.scope_dcache_rsp_ready (scope_dcache_rsp_ready), \
|
||||||
|
.scope_dram_req_valid (scope_dram_req_valid), \
|
||||||
|
.scope_dram_req_tag (scope_dram_req_tag), \
|
||||||
|
.scope_dram_req_ready (scope_dram_req_ready), \
|
||||||
|
.scope_dram_rsp_valid (scope_dram_rsp_valid), \
|
||||||
|
.scope_dram_rsp_tag (scope_dram_rsp_tag), \
|
||||||
|
.scope_dram_rsp_ready (scope_dram_rsp_ready), \
|
||||||
|
.scope_schedule_delay (scope_schedule_delay)
|
||||||
|
|
||||||
|
`define SCOPE_ASSIGN(d,s) assign d = s
|
||||||
|
`else
|
||||||
|
`define SCOPE_SIGNALS_IO()
|
||||||
|
`define SCOPE_SIGNALS_ATTACH()
|
||||||
|
`define SCOPE_ASSIGN(d,s)
|
||||||
|
`endif
|
||||||
|
|
||||||
// VX_DEFINE
|
// VX_DEFINE
|
||||||
`endif
|
`endif
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ module VX_dmem_ctrl # (
|
|||||||
input wire reset,
|
input wire reset,
|
||||||
|
|
||||||
// Core <-> Dcache
|
// Core <-> Dcache
|
||||||
VX_cache_core_req_if dcache_core_req_if,
|
VX_cache_core_req_if core_dcache_req_if,
|
||||||
VX_cache_core_rsp_if dcache_core_rsp_if,
|
VX_cache_core_rsp_if core_dcache_rsp_if,
|
||||||
|
|
||||||
// Dram <-> Dcache
|
// Dram <-> Dcache
|
||||||
VX_cache_dram_req_if dcache_dram_req_if,
|
VX_cache_dram_req_if dcache_dram_req_if,
|
||||||
@@ -17,8 +17,8 @@ module VX_dmem_ctrl # (
|
|||||||
VX_cache_snp_rsp_if dcache_snp_rsp_if,
|
VX_cache_snp_rsp_if dcache_snp_rsp_if,
|
||||||
|
|
||||||
// Core <-> Icache
|
// Core <-> Icache
|
||||||
VX_cache_core_req_if icache_core_req_if,
|
VX_cache_core_req_if core_icache_req_if,
|
||||||
VX_cache_core_rsp_if icache_core_rsp_if,
|
VX_cache_core_rsp_if core_icache_rsp_if,
|
||||||
|
|
||||||
// Dram <-> Icache
|
// Dram <-> Icache
|
||||||
VX_cache_dram_req_if icache_dram_req_if,
|
VX_cache_dram_req_if icache_dram_req_if,
|
||||||
@@ -29,26 +29,26 @@ module VX_dmem_ctrl # (
|
|||||||
.WORD_SIZE (`DWORD_SIZE),
|
.WORD_SIZE (`DWORD_SIZE),
|
||||||
.CORE_TAG_WIDTH (`DCORE_TAG_WIDTH),
|
.CORE_TAG_WIDTH (`DCORE_TAG_WIDTH),
|
||||||
.CORE_TAG_ID_BITS (`DCORE_TAG_ID_BITS)
|
.CORE_TAG_ID_BITS (`DCORE_TAG_ID_BITS)
|
||||||
) dcache_core_req_qual_if(), smem_core_req_if();
|
) core_dcache_req_qual_if(), core_smem_req_if();
|
||||||
|
|
||||||
VX_cache_core_rsp_if #(
|
VX_cache_core_rsp_if #(
|
||||||
.NUM_REQUESTS (`DNUM_REQUESTS),
|
.NUM_REQUESTS (`DNUM_REQUESTS),
|
||||||
.WORD_SIZE (`DWORD_SIZE),
|
.WORD_SIZE (`DWORD_SIZE),
|
||||||
.CORE_TAG_WIDTH (`DCORE_TAG_WIDTH),
|
.CORE_TAG_WIDTH (`DCORE_TAG_WIDTH),
|
||||||
.CORE_TAG_ID_BITS (`DCORE_TAG_ID_BITS)
|
.CORE_TAG_ID_BITS (`DCORE_TAG_ID_BITS)
|
||||||
) dcache_core_rsp_qual_if(), smem_core_rsp_if();
|
) core_dcache_rsp_qual_if(), core_smem_rsp_if();
|
||||||
|
|
||||||
// use "case equality" to handle uninitialized entry
|
// use "case equality" to handle uninitialized entry
|
||||||
wire smem_select = (({dcache_core_req_if.core_req_addr[0], 2'b0} >= `SHARED_MEM_BASE_ADDR) === 1'b1);
|
wire smem_select = (({core_dcache_req_if.core_req_addr[0], 2'b0} >= `SHARED_MEM_BASE_ADDR) === 1'b1);
|
||||||
|
|
||||||
VX_dcache_io_arb dcache_io_arb (
|
VX_dcache_io_arb dcache_io_arb (
|
||||||
.io_select (smem_select),
|
.io_select (smem_select),
|
||||||
.core_req_if (dcache_core_req_if),
|
.core_req_if (core_dcache_req_if),
|
||||||
.dcache_core_req_if (dcache_core_req_qual_if),
|
.core_dcache_req_if (core_dcache_req_qual_if),
|
||||||
.io_core_req_if (smem_core_req_if),
|
.core_io_req_if (core_smem_req_if),
|
||||||
.dcache_core_rsp_if (dcache_core_rsp_qual_if),
|
.core_dcache_rsp_if (core_dcache_rsp_qual_if),
|
||||||
.io_core_rsp_if (smem_core_rsp_if),
|
.core_io_rsp_if (core_smem_rsp_if),
|
||||||
.core_rsp_if (dcache_core_rsp_if)
|
.core_rsp_if (core_dcache_rsp_if)
|
||||||
);
|
);
|
||||||
|
|
||||||
VX_cache #(
|
VX_cache #(
|
||||||
@@ -79,19 +79,19 @@ module VX_dmem_ctrl # (
|
|||||||
.reset (reset),
|
.reset (reset),
|
||||||
|
|
||||||
// Core request
|
// Core request
|
||||||
.core_req_valid (smem_core_req_if.core_req_valid),
|
.core_req_valid (core_smem_req_if.core_req_valid),
|
||||||
.core_req_rw (smem_core_req_if.core_req_rw),
|
.core_req_rw (core_smem_req_if.core_req_rw),
|
||||||
.core_req_byteen (smem_core_req_if.core_req_byteen),
|
.core_req_byteen (core_smem_req_if.core_req_byteen),
|
||||||
.core_req_addr (smem_core_req_if.core_req_addr),
|
.core_req_addr (core_smem_req_if.core_req_addr),
|
||||||
.core_req_data (smem_core_req_if.core_req_data),
|
.core_req_data (core_smem_req_if.core_req_data),
|
||||||
.core_req_tag (smem_core_req_if.core_req_tag),
|
.core_req_tag (core_smem_req_if.core_req_tag),
|
||||||
.core_req_ready (smem_core_req_if.core_req_ready),
|
.core_req_ready (core_smem_req_if.core_req_ready),
|
||||||
|
|
||||||
// Core response
|
// Core response
|
||||||
.core_rsp_valid (smem_core_rsp_if.core_rsp_valid),
|
.core_rsp_valid (core_smem_rsp_if.core_rsp_valid),
|
||||||
.core_rsp_data (smem_core_rsp_if.core_rsp_data),
|
.core_rsp_data (core_smem_rsp_if.core_rsp_data),
|
||||||
.core_rsp_tag (smem_core_rsp_if.core_rsp_tag),
|
.core_rsp_tag (core_smem_rsp_if.core_rsp_tag),
|
||||||
.core_rsp_ready (smem_core_rsp_if.core_rsp_ready),
|
.core_rsp_ready (core_smem_rsp_if.core_rsp_ready),
|
||||||
|
|
||||||
// DRAM request
|
// DRAM request
|
||||||
`UNUSED_PIN (dram_req_valid),
|
`UNUSED_PIN (dram_req_valid),
|
||||||
@@ -160,19 +160,19 @@ module VX_dmem_ctrl # (
|
|||||||
.reset (reset),
|
.reset (reset),
|
||||||
|
|
||||||
// Core req
|
// Core req
|
||||||
.core_req_valid (dcache_core_req_qual_if.core_req_valid),
|
.core_req_valid (core_dcache_req_qual_if.core_req_valid),
|
||||||
.core_req_rw (dcache_core_req_qual_if.core_req_rw),
|
.core_req_rw (core_dcache_req_qual_if.core_req_rw),
|
||||||
.core_req_byteen (dcache_core_req_qual_if.core_req_byteen),
|
.core_req_byteen (core_dcache_req_qual_if.core_req_byteen),
|
||||||
.core_req_addr (dcache_core_req_qual_if.core_req_addr),
|
.core_req_addr (core_dcache_req_qual_if.core_req_addr),
|
||||||
.core_req_data (dcache_core_req_qual_if.core_req_data),
|
.core_req_data (core_dcache_req_qual_if.core_req_data),
|
||||||
.core_req_tag (dcache_core_req_qual_if.core_req_tag),
|
.core_req_tag (core_dcache_req_qual_if.core_req_tag),
|
||||||
.core_req_ready (dcache_core_req_qual_if.core_req_ready),
|
.core_req_ready (core_dcache_req_qual_if.core_req_ready),
|
||||||
|
|
||||||
// Core response
|
// Core response
|
||||||
.core_rsp_valid (dcache_core_rsp_qual_if.core_rsp_valid),
|
.core_rsp_valid (core_dcache_rsp_qual_if.core_rsp_valid),
|
||||||
.core_rsp_data (dcache_core_rsp_qual_if.core_rsp_data),
|
.core_rsp_data (core_dcache_rsp_qual_if.core_rsp_data),
|
||||||
.core_rsp_tag (dcache_core_rsp_qual_if.core_rsp_tag),
|
.core_rsp_tag (core_dcache_rsp_qual_if.core_rsp_tag),
|
||||||
.core_rsp_ready (dcache_core_rsp_qual_if.core_rsp_ready),
|
.core_rsp_ready (core_dcache_rsp_qual_if.core_rsp_ready),
|
||||||
|
|
||||||
// DRAM request
|
// DRAM request
|
||||||
.dram_req_valid (dcache_dram_req_if.dram_req_valid),
|
.dram_req_valid (dcache_dram_req_if.dram_req_valid),
|
||||||
@@ -240,19 +240,19 @@ module VX_dmem_ctrl # (
|
|||||||
.reset (reset),
|
.reset (reset),
|
||||||
|
|
||||||
// Core request
|
// Core request
|
||||||
.core_req_valid (icache_core_req_if.core_req_valid),
|
.core_req_valid (core_icache_req_if.core_req_valid),
|
||||||
.core_req_rw (icache_core_req_if.core_req_rw),
|
.core_req_rw (core_icache_req_if.core_req_rw),
|
||||||
.core_req_byteen (icache_core_req_if.core_req_byteen),
|
.core_req_byteen (core_icache_req_if.core_req_byteen),
|
||||||
.core_req_addr (icache_core_req_if.core_req_addr),
|
.core_req_addr (core_icache_req_if.core_req_addr),
|
||||||
.core_req_data (icache_core_req_if.core_req_data),
|
.core_req_data (core_icache_req_if.core_req_data),
|
||||||
.core_req_tag (icache_core_req_if.core_req_tag),
|
.core_req_tag (core_icache_req_if.core_req_tag),
|
||||||
.core_req_ready (icache_core_req_if.core_req_ready),
|
.core_req_ready (core_icache_req_if.core_req_ready),
|
||||||
|
|
||||||
// Core response
|
// Core response
|
||||||
.core_rsp_valid (icache_core_rsp_if.core_rsp_valid),
|
.core_rsp_valid (core_icache_rsp_if.core_rsp_valid),
|
||||||
.core_rsp_data (icache_core_rsp_if.core_rsp_data),
|
.core_rsp_data (core_icache_rsp_if.core_rsp_data),
|
||||||
.core_rsp_tag (icache_core_rsp_if.core_rsp_tag),
|
.core_rsp_tag (core_icache_rsp_if.core_rsp_tag),
|
||||||
.core_rsp_ready (icache_core_rsp_if.core_rsp_ready),
|
.core_rsp_ready (core_icache_rsp_if.core_rsp_ready),
|
||||||
|
|
||||||
// DRAM Req
|
// DRAM Req
|
||||||
.dram_req_valid (icache_dram_req_if.dram_req_valid),
|
.dram_req_valid (icache_dram_req_if.dram_req_valid),
|
||||||
|
|||||||
185
hw/rtl/VX_pipeline.v
Normal file
185
hw/rtl/VX_pipeline.v
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
`include "VX_define.vh"
|
||||||
|
|
||||||
|
module VX_pipeline #(
|
||||||
|
parameter CORE_ID = 0
|
||||||
|
) (
|
||||||
|
`SCOPE_SIGNALS_IO(),
|
||||||
|
|
||||||
|
// Clock
|
||||||
|
input wire clk,
|
||||||
|
input wire reset,
|
||||||
|
|
||||||
|
// Dcache core request
|
||||||
|
output wire [`NUM_THREADS-1:0] dcache_req_valid,
|
||||||
|
output wire [`NUM_THREADS-1:0] dcache_req_rw,
|
||||||
|
output wire [`NUM_THREADS-1:0][3:0] dcache_req_byteen,
|
||||||
|
output wire [`NUM_THREADS-1:0][29:0] dcache_req_addr,
|
||||||
|
output wire [`NUM_THREADS-1:0][31:0] dcache_req_data,
|
||||||
|
output wire [`DCORE_TAG_WIDTH-1:0] dcache_req_tag,
|
||||||
|
input wire dcache_req_ready,
|
||||||
|
|
||||||
|
// Dcache core reponse
|
||||||
|
input wire [`NUM_THREADS-1:0] dcache_rsp_valid,
|
||||||
|
input wire [`NUM_THREADS-1:0][31:0] dcache_rsp_data,
|
||||||
|
input wire [`DCORE_TAG_WIDTH-1:0] dcache_rsp_tag,
|
||||||
|
output wire dcache_rsp_ready,
|
||||||
|
|
||||||
|
// Icache core request
|
||||||
|
output wire icache_req_valid,
|
||||||
|
output wire icache_req_rw,
|
||||||
|
output wire [3:0] icache_req_byteen,
|
||||||
|
output wire [29:0] icache_req_addr,
|
||||||
|
output wire [31:0] icache_req_data,
|
||||||
|
output wire [`ICORE_TAG_WIDTH-1:0] icache_req_tag,
|
||||||
|
input wire icache_req_ready,
|
||||||
|
|
||||||
|
// Icache core response
|
||||||
|
input wire icache_rsp_valid,
|
||||||
|
input wire [31:0] icache_rsp_data,
|
||||||
|
input wire [`ICORE_TAG_WIDTH-1:0] icache_rsp_tag,
|
||||||
|
output wire icache_rsp_ready,
|
||||||
|
|
||||||
|
// Status
|
||||||
|
output wire busy,
|
||||||
|
output wire ebreak
|
||||||
|
);
|
||||||
|
|
||||||
|
`DEBUG_BEGIN
|
||||||
|
wire scheduler_empty;
|
||||||
|
`DEBUG_END
|
||||||
|
|
||||||
|
wire memory_delay;
|
||||||
|
wire exec_delay;
|
||||||
|
wire gpr_stage_delay;
|
||||||
|
wire schedule_delay;
|
||||||
|
|
||||||
|
`SCOPE_ASSIGN(scope_schedule_delay, schedule_delay);
|
||||||
|
|
||||||
|
`SCOPE_ASSIGN(scope_dcache_req_valid, dcache_req_valid);
|
||||||
|
`SCOPE_ASSIGN(scope_dcache_req_tag, dcache_req_tag);
|
||||||
|
`SCOPE_ASSIGN(scope_dcache_req_ready, dcache_req_ready);
|
||||||
|
`SCOPE_ASSIGN(scope_dcache_rsp_valid, dcache_rsp_valid);
|
||||||
|
`SCOPE_ASSIGN(scope_dcache_rsp_tag, dcache_rsp_tag);
|
||||||
|
`SCOPE_ASSIGN(scope_dcache_rsp_ready, dcache_rsp_ready);
|
||||||
|
|
||||||
|
`SCOPE_ASSIGN(scope_icache_req_valid, icache_req_valid);
|
||||||
|
`SCOPE_ASSIGN(scope_icache_req_tag, icache_req_tag);
|
||||||
|
`SCOPE_ASSIGN(scope_icache_req_ready, icache_req_ready);
|
||||||
|
`SCOPE_ASSIGN(scope_icache_rsp_valid, icache_rsp_valid);
|
||||||
|
`SCOPE_ASSIGN(scope_icache_rsp_tag, icache_rsp_tag);
|
||||||
|
`SCOPE_ASSIGN(scope_icache_rsp_ready, icache_rsp_ready);
|
||||||
|
|
||||||
|
// Dcache
|
||||||
|
VX_cache_core_req_if #(
|
||||||
|
.NUM_REQUESTS(`NUM_THREADS),
|
||||||
|
.WORD_SIZE(4),
|
||||||
|
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
||||||
|
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
||||||
|
) core_dcache_req_if();
|
||||||
|
|
||||||
|
VX_cache_core_rsp_if #(
|
||||||
|
.NUM_REQUESTS(`NUM_THREADS),
|
||||||
|
.WORD_SIZE(4),
|
||||||
|
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
||||||
|
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
||||||
|
) core_dcache_rsp_if();
|
||||||
|
|
||||||
|
// Icache
|
||||||
|
VX_cache_core_req_if #(
|
||||||
|
.NUM_REQUESTS(1),
|
||||||
|
.WORD_SIZE(4),
|
||||||
|
.CORE_TAG_WIDTH(`ICORE_TAG_WIDTH),
|
||||||
|
.CORE_TAG_ID_BITS(`ICORE_TAG_ID_BITS)
|
||||||
|
) core_icache_req_if();
|
||||||
|
|
||||||
|
VX_cache_core_rsp_if #(
|
||||||
|
.NUM_REQUESTS(1),
|
||||||
|
.WORD_SIZE(4),
|
||||||
|
.CORE_TAG_WIDTH(`ICORE_TAG_WIDTH),
|
||||||
|
.CORE_TAG_ID_BITS(`ICORE_TAG_ID_BITS)
|
||||||
|
) core_icache_rsp_if();
|
||||||
|
|
||||||
|
// Front-end to Back-end
|
||||||
|
VX_frE_to_bckE_req_if bckE_req_if();
|
||||||
|
|
||||||
|
// Back-end to Front-end
|
||||||
|
VX_wb_if writeback_if();
|
||||||
|
VX_branch_rsp_if branch_rsp_if();
|
||||||
|
VX_jal_rsp_if jal_rsp_if();
|
||||||
|
|
||||||
|
// Warp controls
|
||||||
|
VX_warp_ctl_if warp_ctl_if();
|
||||||
|
|
||||||
|
VX_front_end #(
|
||||||
|
.CORE_ID(CORE_ID)
|
||||||
|
) front_end (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.warp_ctl_if (warp_ctl_if),
|
||||||
|
.bckE_req_if (bckE_req_if),
|
||||||
|
.schedule_delay (schedule_delay),
|
||||||
|
.icache_rsp_if (core_icache_rsp_if),
|
||||||
|
.icache_req_if (core_icache_req_if),
|
||||||
|
.jal_rsp_if (jal_rsp_if),
|
||||||
|
.branch_rsp_if (branch_rsp_if),
|
||||||
|
.busy (busy)
|
||||||
|
);
|
||||||
|
|
||||||
|
VX_scheduler scheduler (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.memory_delay (memory_delay),
|
||||||
|
.exec_delay (exec_delay),
|
||||||
|
.gpr_stage_delay(gpr_stage_delay),
|
||||||
|
.bckE_req_if (bckE_req_if),
|
||||||
|
.writeback_if (writeback_if),
|
||||||
|
.schedule_delay (schedule_delay),
|
||||||
|
.is_empty (scheduler_empty)
|
||||||
|
);
|
||||||
|
|
||||||
|
VX_back_end #(
|
||||||
|
.CORE_ID(CORE_ID)
|
||||||
|
) back_end (
|
||||||
|
.clk (clk),
|
||||||
|
.reset (reset),
|
||||||
|
.schedule_delay (schedule_delay),
|
||||||
|
.warp_ctl_if (warp_ctl_if),
|
||||||
|
.bckE_req_if (bckE_req_if),
|
||||||
|
.jal_rsp_if (jal_rsp_if),
|
||||||
|
.branch_rsp_if (branch_rsp_if),
|
||||||
|
.dcache_req_if (core_dcache_req_if),
|
||||||
|
.dcache_rsp_if (core_dcache_rsp_if),
|
||||||
|
.writeback_if (writeback_if),
|
||||||
|
.mem_delay (memory_delay),
|
||||||
|
.exec_delay (exec_delay),
|
||||||
|
.gpr_stage_delay (gpr_stage_delay),
|
||||||
|
.ebreak (ebreak)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign dcache_req_valid = core_dcache_req_if.core_req_valid;
|
||||||
|
assign dcache_req_rw = core_dcache_req_if.core_req_rw;
|
||||||
|
assign dcache_req_byteen = core_dcache_req_if.core_req_byteen;
|
||||||
|
assign dcache_req_addr = core_dcache_req_if.core_req_addr;
|
||||||
|
assign dcache_req_data = core_dcache_req_if.core_req_data;
|
||||||
|
assign dcache_req_tag = core_dcache_req_if.core_req_tag;
|
||||||
|
assign core_dcache_req_if.core_req_ready = dcache_req_ready;
|
||||||
|
|
||||||
|
assign core_dcache_rsp_if.core_rsp_valid = dcache_rsp_valid;
|
||||||
|
assign core_dcache_rsp_if.core_rsp_data = dcache_rsp_data;
|
||||||
|
assign core_dcache_rsp_if.core_rsp_tag = dcache_rsp_tag;
|
||||||
|
assign dcache_rsp_ready = core_dcache_rsp_if.core_rsp_ready;
|
||||||
|
|
||||||
|
assign icache_req_valid = core_icache_req_if.core_req_valid;
|
||||||
|
assign icache_req_rw = core_icache_req_if.core_req_rw;
|
||||||
|
assign icache_req_byteen = core_icache_req_if.core_req_byteen;
|
||||||
|
assign icache_req_addr = core_icache_req_if.core_req_addr;
|
||||||
|
assign icache_req_data = core_icache_req_if.core_req_data;
|
||||||
|
assign icache_req_tag = core_icache_req_if.core_req_tag;
|
||||||
|
assign core_icache_req_if.core_req_ready = icache_req_ready;
|
||||||
|
|
||||||
|
assign core_icache_rsp_if.core_rsp_valid = icache_rsp_valid;
|
||||||
|
assign core_icache_rsp_if.core_rsp_data = icache_rsp_data;
|
||||||
|
assign core_icache_rsp_if.core_rsp_tag = icache_rsp_tag;
|
||||||
|
assign icache_rsp_ready = core_icache_rsp_if.core_rsp_ready;
|
||||||
|
|
||||||
|
endmodule // Vortex
|
||||||
196
hw/rtl/Vortex.v
196
hw/rtl/Vortex.v
@@ -3,6 +3,8 @@
|
|||||||
module Vortex #(
|
module Vortex #(
|
||||||
parameter CORE_ID = 0
|
parameter CORE_ID = 0
|
||||||
) (
|
) (
|
||||||
|
`SCOPE_SIGNALS_IO(),
|
||||||
|
|
||||||
// Clock
|
// Clock
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire reset,
|
input wire reset,
|
||||||
@@ -66,29 +68,7 @@ module Vortex #(
|
|||||||
output wire busy,
|
output wire busy,
|
||||||
output wire ebreak
|
output wire ebreak
|
||||||
);
|
);
|
||||||
`DEBUG_BEGIN
|
|
||||||
wire scheduler_empty;
|
|
||||||
`DEBUG_END
|
|
||||||
|
|
||||||
wire memory_delay;
|
|
||||||
wire exec_delay;
|
|
||||||
wire gpr_stage_delay;
|
|
||||||
wire schedule_delay;
|
|
||||||
|
|
||||||
// Dcache Interfaces
|
// Dcache Interfaces
|
||||||
VX_cache_core_req_if #(
|
|
||||||
.NUM_REQUESTS(`DNUM_REQUESTS),
|
|
||||||
.WORD_SIZE(`DWORD_SIZE),
|
|
||||||
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
|
||||||
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
|
||||||
) dcache_core_req_if(), io_core_req_if(), dcache_io_core_req_if();
|
|
||||||
|
|
||||||
VX_cache_core_rsp_if #(
|
|
||||||
.NUM_REQUESTS(`DNUM_REQUESTS),
|
|
||||||
.WORD_SIZE(`DWORD_SIZE),
|
|
||||||
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
|
||||||
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
|
||||||
) dcache_core_rsp_if(), io_core_rsp_if(), dcache_io_core_rsp_if();
|
|
||||||
|
|
||||||
VX_cache_dram_req_if #(
|
VX_cache_dram_req_if #(
|
||||||
.DRAM_LINE_WIDTH(`DDRAM_LINE_WIDTH),
|
.DRAM_LINE_WIDTH(`DDRAM_LINE_WIDTH),
|
||||||
@@ -114,33 +94,34 @@ module Vortex #(
|
|||||||
assign dcache_dram_rsp_if.dram_rsp_tag = D_dram_rsp_tag;
|
assign dcache_dram_rsp_if.dram_rsp_tag = D_dram_rsp_tag;
|
||||||
assign D_dram_rsp_ready = dcache_dram_rsp_if.dram_rsp_ready;
|
assign D_dram_rsp_ready = dcache_dram_rsp_if.dram_rsp_ready;
|
||||||
|
|
||||||
assign io_req_valid = io_core_req_if.core_req_valid[0];
|
|
||||||
assign io_req_rw = io_core_req_if.core_req_rw[0];
|
|
||||||
assign io_req_byteen = io_core_req_if.core_req_byteen[0];
|
|
||||||
assign io_req_addr = io_core_req_if.core_req_addr[0];
|
|
||||||
assign io_req_data = io_core_req_if.core_req_data[0];
|
|
||||||
assign io_req_tag = io_core_req_if.core_req_tag[0];
|
|
||||||
assign io_core_req_if.core_req_ready = io_req_ready;
|
|
||||||
|
|
||||||
assign io_core_rsp_if.core_rsp_valid = {{(`NUM_THREADS-1){1'b0}}, io_rsp_valid};
|
|
||||||
assign io_core_rsp_if.core_rsp_data[0] = io_rsp_data;
|
|
||||||
assign io_core_rsp_if.core_rsp_tag = io_rsp_tag;
|
|
||||||
assign io_rsp_ready = io_core_rsp_if.core_rsp_ready;
|
|
||||||
|
|
||||||
// Icache interfaces
|
|
||||||
VX_cache_core_req_if #(
|
VX_cache_core_req_if #(
|
||||||
.NUM_REQUESTS(`INUM_REQUESTS),
|
.NUM_REQUESTS(`DNUM_REQUESTS),
|
||||||
.WORD_SIZE(`IWORD_SIZE),
|
.WORD_SIZE(`DWORD_SIZE),
|
||||||
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
||||||
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
||||||
) icache_core_req_if();
|
) core_dcache_req_if(),arb_dcache_req_if(), arb_io_req_if();
|
||||||
|
|
||||||
VX_cache_core_rsp_if #(
|
VX_cache_core_rsp_if #(
|
||||||
.NUM_REQUESTS(`INUM_REQUESTS),
|
.NUM_REQUESTS(`DNUM_REQUESTS),
|
||||||
.WORD_SIZE(`IWORD_SIZE),
|
.WORD_SIZE(`DWORD_SIZE),
|
||||||
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
||||||
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
||||||
) icache_core_rsp_if();
|
) core_dcache_rsp_if(), arb_dcache_rsp_if(), arb_io_rsp_if();
|
||||||
|
|
||||||
|
assign io_req_valid = arb_io_req_if.core_req_valid[0];
|
||||||
|
assign io_req_rw = arb_io_req_if.core_req_rw[0];
|
||||||
|
assign io_req_byteen = arb_io_req_if.core_req_byteen[0];
|
||||||
|
assign io_req_addr = arb_io_req_if.core_req_addr[0];
|
||||||
|
assign io_req_data = arb_io_req_if.core_req_data[0];
|
||||||
|
assign io_req_tag = arb_io_req_if.core_req_tag[0];
|
||||||
|
assign arb_io_req_if.core_req_ready = io_req_ready;
|
||||||
|
|
||||||
|
assign arb_io_rsp_if.core_rsp_valid = {{(`NUM_THREADS-1){1'b0}}, io_rsp_valid};
|
||||||
|
assign arb_io_rsp_if.core_rsp_data[0] = io_rsp_data;
|
||||||
|
assign arb_io_rsp_if.core_rsp_tag = io_rsp_tag;
|
||||||
|
assign io_rsp_ready = arb_io_rsp_if.core_rsp_ready;
|
||||||
|
|
||||||
|
// Icache interfaces
|
||||||
|
|
||||||
VX_cache_dram_req_if #(
|
VX_cache_dram_req_if #(
|
||||||
.DRAM_LINE_WIDTH(`IDRAM_LINE_WIDTH),
|
.DRAM_LINE_WIDTH(`IDRAM_LINE_WIDTH),
|
||||||
@@ -166,18 +147,63 @@ module Vortex #(
|
|||||||
assign icache_dram_rsp_if.dram_rsp_tag = I_dram_rsp_tag;
|
assign icache_dram_rsp_if.dram_rsp_tag = I_dram_rsp_tag;
|
||||||
assign I_dram_rsp_ready = icache_dram_rsp_if.dram_rsp_ready;
|
assign I_dram_rsp_ready = icache_dram_rsp_if.dram_rsp_ready;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
VX_cache_core_req_if #(
|
||||||
|
.NUM_REQUESTS(`INUM_REQUESTS),
|
||||||
|
.WORD_SIZE(`IWORD_SIZE),
|
||||||
|
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
||||||
|
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
||||||
|
) core_icache_req_if();
|
||||||
|
|
||||||
// Front-end to Back-end
|
VX_cache_core_rsp_if #(
|
||||||
VX_frE_to_bckE_req_if bckE_req_if(); // New instruction request to EXE/MEM
|
.NUM_REQUESTS(`INUM_REQUESTS),
|
||||||
|
.WORD_SIZE(`IWORD_SIZE),
|
||||||
|
.CORE_TAG_WIDTH(`DCORE_TAG_WIDTH),
|
||||||
|
.CORE_TAG_ID_BITS(`DCORE_TAG_ID_BITS)
|
||||||
|
) core_icache_rsp_if();
|
||||||
|
|
||||||
// Back-end to Front-end
|
// Vortex pipeline
|
||||||
VX_wb_if writeback_if(); // Writeback to GPRs
|
VX_pipeline #(
|
||||||
VX_branch_rsp_if branch_rsp_if(); // Branch Resolution to Fetch
|
.CORE_ID(CORE_ID)
|
||||||
VX_jal_rsp_if jal_rsp_if(); // Jump resolution to Fetch
|
) pipeline (
|
||||||
|
`SCOPE_SIGNALS_ATTACH(),
|
||||||
|
|
||||||
// Warp controls
|
.clk(clk),
|
||||||
VX_warp_ctl_if warp_ctl_if();
|
.reset(reset),
|
||||||
|
|
||||||
|
// Dcache core request
|
||||||
|
.dcache_req_valid (core_dcache_req_if.core_req_valid),
|
||||||
|
.dcache_req_rw (core_dcache_req_if.core_req_rw),
|
||||||
|
.dcache_req_byteen (core_dcache_req_if.core_req_byteen),
|
||||||
|
.dcache_req_addr (core_dcache_req_if.core_req_addr),
|
||||||
|
.dcache_req_data (core_dcache_req_if.core_req_data),
|
||||||
|
.dcache_req_tag (core_dcache_req_if.core_req_tag),
|
||||||
|
.dcache_req_ready (core_dcache_req_if.core_req_ready),
|
||||||
|
|
||||||
|
// Dcache core reponse
|
||||||
|
.dcache_rsp_valid (core_dcache_rsp_if.core_rsp_valid),
|
||||||
|
.dcache_rsp_data (core_dcache_rsp_if.core_rsp_data),
|
||||||
|
.dcache_rsp_tag (core_dcache_rsp_if.core_rsp_tag),
|
||||||
|
.dcache_rsp_ready (core_dcache_rsp_if.core_rsp_ready),
|
||||||
|
|
||||||
|
// Dcache core request
|
||||||
|
.icache_req_valid (core_icache_req_if.core_req_valid),
|
||||||
|
.icache_req_rw (core_icache_req_if.core_req_rw),
|
||||||
|
.icache_req_byteen (core_icache_req_if.core_req_byteen),
|
||||||
|
.icache_req_addr (core_icache_req_if.core_req_addr),
|
||||||
|
.icache_req_data (core_icache_req_if.core_req_data),
|
||||||
|
.icache_req_tag (core_icache_req_if.core_req_tag),
|
||||||
|
.icache_req_ready (core_icache_req_if.core_req_ready),
|
||||||
|
|
||||||
|
// Dcache core reponse
|
||||||
|
.icache_rsp_valid (core_icache_rsp_if.core_rsp_valid),
|
||||||
|
.icache_rsp_data (core_icache_rsp_if.core_rsp_data),
|
||||||
|
.icache_rsp_tag (core_icache_rsp_if.core_rsp_tag),
|
||||||
|
.icache_rsp_ready (core_icache_rsp_if.core_rsp_ready),
|
||||||
|
|
||||||
|
// Status
|
||||||
|
.busy(busy),
|
||||||
|
.ebreak(ebreak)
|
||||||
|
);
|
||||||
|
|
||||||
// Cache snooping
|
// Cache snooping
|
||||||
VX_cache_snp_req_if #(
|
VX_cache_snp_req_if #(
|
||||||
@@ -198,52 +224,6 @@ module Vortex #(
|
|||||||
assign snp_rsp_tag = dcache_snp_rsp_if.snp_rsp_tag;
|
assign snp_rsp_tag = dcache_snp_rsp_if.snp_rsp_tag;
|
||||||
assign dcache_snp_rsp_if.snp_rsp_ready = snp_rsp_ready;
|
assign dcache_snp_rsp_if.snp_rsp_ready = snp_rsp_ready;
|
||||||
|
|
||||||
VX_front_end #(
|
|
||||||
.CORE_ID(CORE_ID)
|
|
||||||
) front_end (
|
|
||||||
.clk (clk),
|
|
||||||
.reset (reset),
|
|
||||||
.warp_ctl_if (warp_ctl_if),
|
|
||||||
.bckE_req_if (bckE_req_if),
|
|
||||||
.schedule_delay (schedule_delay),
|
|
||||||
.icache_rsp_if (icache_core_rsp_if),
|
|
||||||
.icache_req_if (icache_core_req_if),
|
|
||||||
.jal_rsp_if (jal_rsp_if),
|
|
||||||
.branch_rsp_if (branch_rsp_if),
|
|
||||||
.busy (busy)
|
|
||||||
);
|
|
||||||
|
|
||||||
VX_scheduler scheduler (
|
|
||||||
.clk (clk),
|
|
||||||
.reset (reset),
|
|
||||||
.memory_delay (memory_delay),
|
|
||||||
.exec_delay (exec_delay),
|
|
||||||
.gpr_stage_delay(gpr_stage_delay),
|
|
||||||
.bckE_req_if (bckE_req_if),
|
|
||||||
.writeback_if (writeback_if),
|
|
||||||
.schedule_delay (schedule_delay),
|
|
||||||
.is_empty (scheduler_empty)
|
|
||||||
);
|
|
||||||
|
|
||||||
VX_back_end #(
|
|
||||||
.CORE_ID(CORE_ID)
|
|
||||||
) back_end (
|
|
||||||
.clk (clk),
|
|
||||||
.reset (reset),
|
|
||||||
.schedule_delay (schedule_delay),
|
|
||||||
.warp_ctl_if (warp_ctl_if),
|
|
||||||
.bckE_req_if (bckE_req_if),
|
|
||||||
.jal_rsp_if (jal_rsp_if),
|
|
||||||
.branch_rsp_if (branch_rsp_if),
|
|
||||||
.dcache_req_if (dcache_io_core_req_if),
|
|
||||||
.dcache_rsp_if (dcache_io_core_rsp_if),
|
|
||||||
.writeback_if (writeback_if),
|
|
||||||
.mem_delay (memory_delay),
|
|
||||||
.exec_delay (exec_delay),
|
|
||||||
.gpr_stage_delay (gpr_stage_delay),
|
|
||||||
.ebreak (ebreak)
|
|
||||||
);
|
|
||||||
|
|
||||||
VX_dmem_ctrl #(
|
VX_dmem_ctrl #(
|
||||||
.CORE_ID(CORE_ID)
|
.CORE_ID(CORE_ID)
|
||||||
) dmem_ctrl (
|
) dmem_ctrl (
|
||||||
@@ -251,8 +231,8 @@ module Vortex #(
|
|||||||
.reset (reset),
|
.reset (reset),
|
||||||
|
|
||||||
// Core <-> Dcache
|
// Core <-> Dcache
|
||||||
.dcache_core_req_if (dcache_core_req_if),
|
.core_dcache_req_if (arb_dcache_req_if),
|
||||||
.dcache_core_rsp_if (dcache_core_rsp_if),
|
.core_dcache_rsp_if (arb_dcache_rsp_if),
|
||||||
|
|
||||||
// Dram <-> Dcache
|
// Dram <-> Dcache
|
||||||
.dcache_dram_req_if (dcache_dram_req_if),
|
.dcache_dram_req_if (dcache_dram_req_if),
|
||||||
@@ -261,8 +241,8 @@ module Vortex #(
|
|||||||
.dcache_snp_rsp_if (dcache_snp_rsp_if),
|
.dcache_snp_rsp_if (dcache_snp_rsp_if),
|
||||||
|
|
||||||
// Core <-> Icache
|
// Core <-> Icache
|
||||||
.icache_core_req_if (icache_core_req_if),
|
.core_icache_req_if (core_icache_req_if),
|
||||||
.icache_core_rsp_if (icache_core_rsp_if),
|
.core_icache_rsp_if (core_icache_rsp_if),
|
||||||
|
|
||||||
// Dram <-> Icache
|
// Dram <-> Icache
|
||||||
.icache_dram_req_if (icache_dram_req_if),
|
.icache_dram_req_if (icache_dram_req_if),
|
||||||
@@ -270,16 +250,16 @@ module Vortex #(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// use "case equality" to handle uninitialized address value
|
// use "case equality" to handle uninitialized address value
|
||||||
wire io_select = (({dcache_io_core_req_if.core_req_addr[0], 2'b0} >= `IO_BUS_BASE_ADDR) === 1'b1);
|
wire io_select = (({core_dcache_req_if.core_req_addr[0], 2'b0} >= `IO_BUS_BASE_ADDR) === 1'b1);
|
||||||
|
|
||||||
VX_dcache_io_arb dcache_io_arb (
|
VX_dcache_io_arb dcache_io_arb (
|
||||||
.io_select (io_select),
|
.io_select (io_select),
|
||||||
.core_req_if (dcache_io_core_req_if),
|
.core_req_if (core_dcache_req_if),
|
||||||
.dcache_core_req_if (dcache_core_req_if),
|
.core_dcache_req_if (arb_dcache_req_if),
|
||||||
.io_core_req_if (io_core_req_if),
|
.core_io_req_if (arb_io_req_if),
|
||||||
.dcache_core_rsp_if (dcache_core_rsp_if),
|
.core_dcache_rsp_if (arb_dcache_rsp_if),
|
||||||
.io_core_rsp_if (io_core_rsp_if),
|
.core_io_rsp_if (arb_io_rsp_if),
|
||||||
.core_rsp_if (dcache_io_core_rsp_if)
|
.core_rsp_if (core_dcache_rsp_if)
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule // Vortex
|
endmodule // Vortex
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
module Vortex_Cluster #(
|
module Vortex_Cluster #(
|
||||||
parameter CLUSTER_ID = 0
|
parameter CLUSTER_ID = 0
|
||||||
) (
|
) (
|
||||||
|
`SCOPE_SIGNALS_IO(),
|
||||||
|
|
||||||
// Clock
|
// Clock
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire reset,
|
input wire reset,
|
||||||
@@ -106,6 +108,8 @@ module Vortex_Cluster #(
|
|||||||
Vortex #(
|
Vortex #(
|
||||||
.CORE_ID(i + (CLUSTER_ID * `NUM_CORES))
|
.CORE_ID(i + (CLUSTER_ID * `NUM_CORES))
|
||||||
) vortex_core (
|
) vortex_core (
|
||||||
|
`SCOPE_SIGNALS_ATTACH(),
|
||||||
|
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.reset (reset),
|
.reset (reset),
|
||||||
.D_dram_req_valid (per_core_D_dram_req_valid [i]),
|
.D_dram_req_valid (per_core_D_dram_req_valid [i]),
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
`include "VX_define.vh"
|
`include "VX_define.vh"
|
||||||
|
|
||||||
module Vortex_Socket (
|
module Vortex_Socket (
|
||||||
|
`SCOPE_SIGNALS_IO(),
|
||||||
|
|
||||||
// Clock
|
// Clock
|
||||||
input wire clk,
|
input wire clk,
|
||||||
input wire reset,
|
input wire reset,
|
||||||
@@ -50,11 +52,20 @@ module Vortex_Socket (
|
|||||||
output wire busy,
|
output wire busy,
|
||||||
output wire ebreak
|
output wire ebreak
|
||||||
);
|
);
|
||||||
|
`SCOPE_ASSIGN(scope_dram_req_valid, dram_req_valid);
|
||||||
|
`SCOPE_ASSIGN(scope_dram_req_tag, dram_req_tag);
|
||||||
|
`SCOPE_ASSIGN(scope_dram_req_ready, dram_req_ready);
|
||||||
|
`SCOPE_ASSIGN(scope_dram_rsp_valid, dram_rsp_valid);
|
||||||
|
`SCOPE_ASSIGN(scope_dram_rsp_tag, dram_req_tag);
|
||||||
|
`SCOPE_ASSIGN(scope_dram_rsp_ready, dram_rsp_ready);
|
||||||
|
|
||||||
if (`NUM_CLUSTERS == 1) begin
|
if (`NUM_CLUSTERS == 1) begin
|
||||||
|
|
||||||
Vortex_Cluster #(
|
Vortex_Cluster #(
|
||||||
.CLUSTER_ID(`L3CACHE_ID)
|
.CLUSTER_ID(`L3CACHE_ID)
|
||||||
) Vortex_Cluster (
|
) Vortex_Cluster (
|
||||||
|
`SCOPE_SIGNALS_ATTACH(),
|
||||||
|
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.reset (reset),
|
.reset (reset),
|
||||||
|
|
||||||
@@ -140,6 +151,8 @@ module Vortex_Socket (
|
|||||||
Vortex_Cluster #(
|
Vortex_Cluster #(
|
||||||
.CLUSTER_ID(i)
|
.CLUSTER_ID(i)
|
||||||
) Vortex_Cluster (
|
) Vortex_Cluster (
|
||||||
|
`SCOPE_SIGNALS_ATTACH(),
|
||||||
|
|
||||||
.clk (clk),
|
.clk (clk),
|
||||||
.reset (reset),
|
.reset (reset),
|
||||||
|
|
||||||
|
|||||||
87
hw/rtl/libs/VX_scope.v
Normal file
87
hw/rtl/libs/VX_scope.v
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
module VX_scope #(
|
||||||
|
parameter DATAW = 64,
|
||||||
|
parameter BUSW = 64,
|
||||||
|
parameter SIZE = 1024
|
||||||
|
) (
|
||||||
|
input wire clk,
|
||||||
|
input wire reset,
|
||||||
|
input wire start,
|
||||||
|
input wire [DATAW-1:0] data_in,
|
||||||
|
input wire [BUSW-1:0] bus_in,
|
||||||
|
output wire [BUSW-1:0] bus_out,
|
||||||
|
input wire bus_write,
|
||||||
|
input wire bus_read
|
||||||
|
);
|
||||||
|
reg [DATAW-1:0] mem [SIZE-1:0];
|
||||||
|
|
||||||
|
reg [`CLOG2(SIZE)-1:0] raddr, waddr;
|
||||||
|
|
||||||
|
reg started, running, done;
|
||||||
|
|
||||||
|
reg [BUSW-1:0] delay_cntr;
|
||||||
|
|
||||||
|
reg data_valid, data_end;
|
||||||
|
|
||||||
|
reg [`LOG2UP(DATAW)-1:0] read_offset;
|
||||||
|
|
||||||
|
wire [BUSW-3:0] data_part;
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (reset) begin
|
||||||
|
raddr <= 0;
|
||||||
|
waddr <= 0;
|
||||||
|
started <= 0;
|
||||||
|
running <= 0;
|
||||||
|
done <= 0;
|
||||||
|
delay_cntr <= 0;
|
||||||
|
read_offset <= 0;
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
if (bus_write) begin
|
||||||
|
delay_cntr <= bus_in;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (start) begin
|
||||||
|
started <= 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (start || started) begin
|
||||||
|
if (0 == delay_cntr) begin
|
||||||
|
running <= 1;
|
||||||
|
end else begin
|
||||||
|
delay_cntr <= delay_cntr - 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (running && !done) begin
|
||||||
|
mem[waddr] <= data_in;
|
||||||
|
waddr <= waddr + 1;
|
||||||
|
if (waddr == $bits(waddr)'(SIZE-1)) begin
|
||||||
|
done <= 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (bus_read) begin
|
||||||
|
if (DATAW > (BUSW-2)) begin
|
||||||
|
if (read_offset < $bits(read_offset)'(DATAW-(BUSW-2))) begin
|
||||||
|
read_offset <= read_offset + $bits(read_offset)'(BUSW-2);
|
||||||
|
end else begin
|
||||||
|
read_offset <= 0;
|
||||||
|
raddr <= raddr + 1;
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
raddr <= raddr + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign data_valid = (waddr != 0) && (raddr <= waddr);
|
||||||
|
|
||||||
|
assign data_end = (0 == read_offset) || (raddr == waddr);
|
||||||
|
|
||||||
|
assign data_part = (BUSW-2)'(mem[raddr] >> read_offset);
|
||||||
|
|
||||||
|
assign bus_out = {data_valid, data_end, data_part};
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -8,12 +8,12 @@ CXXFLAGS ?= -std=c++11 -fPIC -O3 -Wall -Wextra -pedantic -DUSE_DEBUG=3 -DPRINT_A
|
|||||||
LIB_OBJS=simX.cpp args.cpp mem.cpp core.cpp instruction.cpp enc.cpp util.cpp
|
LIB_OBJS=simX.cpp args.cpp mem.cpp core.cpp instruction.cpp enc.cpp util.cpp
|
||||||
|
|
||||||
|
|
||||||
INCLUDE=-I. -I../hw/old_rtl -I../hw/old_rtl/interfaces -I../hw/old_rtl/cache -I../hw/old_rtl/shared_memory
|
INCLUDE=-I../hw/old_rtl -I../hw/old_rtl/interfaces -I../hw/old_rtl/cache -I../hw/old_rtl/shared_memory
|
||||||
FILE=cache_simX.v
|
FILE=cache_simX.v
|
||||||
COMP=--compiler gcc
|
COMP=--compiler gcc
|
||||||
LIB=
|
LIB=
|
||||||
|
|
||||||
CF=-CFLAGS '-std=c++11 -fPIC -O3 -Wall -Wextra -pedantic'
|
CF=-CFLAGS '-std=c++11 -fPIC -O3 -Wall -Wextra -pedantic -I../../hw'
|
||||||
#CF=-CFLAGS '-std=c++11 -fPIC -O0 -g -Wall -Wextra -pedantic'
|
#CF=-CFLAGS '-std=c++11 -fPIC -O0 -g -Wall -Wextra -pedantic'
|
||||||
|
|
||||||
LIGHTW=-Wno-UNOPTFLAT -Wno-WIDTH
|
LIGHTW=-Wno-UNOPTFLAT -Wno-WIDTH
|
||||||
|
|||||||
@@ -60,8 +60,8 @@ int emu_main(int argc, char **argv) {
|
|||||||
string archString("rv32i");
|
string archString("rv32i");
|
||||||
string imgFileName("a.dsfsdout.bin");
|
string imgFileName("a.dsfsdout.bin");
|
||||||
bool showHelp(false), showStats(false), basicMachine(true);
|
bool showHelp(false), showStats(false), basicMachine(true);
|
||||||
int max_warps(NW);
|
int max_warps(NUM_WARPS);
|
||||||
int max_threads(NT);
|
int max_threads(NUM_THREADS);
|
||||||
|
|
||||||
/* Read the command line arguments. */
|
/* Read the command line arguments. */
|
||||||
CommandLineArgFlag fh("-h", "--help", "", showHelp);
|
CommandLineArgFlag fh("-h", "--help", "", showHelp);
|
||||||
|
|||||||
Reference in New Issue
Block a user