cache flush support

This commit is contained in:
Blaise Tine 2021-01-17 05:50:29 -08:00
parent d4e7b28be8
commit a69ba5ad7b
10 changed files with 133 additions and 107 deletions

View file

@ -1,5 +1,6 @@
+define+NUM_CORES=8
+define+NUM_CLUSTERS=1
+define+NUM_CORES=4
+define+NUM_CLUSTERS=2
+define+L3_ENABLE=1
+define+SYNTHESIS
+define+QUARTUS

View file

@ -182,6 +182,8 @@ module VX_cluster #(
.clk (clk),
.reset (reset),
.flush (1'b0),
`ifdef PERF_ENABLE
.perf_cache_if (perf_l2cache_if),
`endif

View file

@ -264,7 +264,7 @@
// Size of cache in bytes
`ifndef ICACHE_SIZE
`define ICACHE_SIZE 16384
`define ICACHE_SIZE 8192
`endif
// Core Request Queue Size
@ -296,7 +296,7 @@
// Size of cache in bytes
`ifndef DCACHE_SIZE
`define DCACHE_SIZE 16384
`define DCACHE_SIZE 8192
`endif
// Number of banks
@ -360,7 +360,7 @@
// Size of cache in bytes
`ifndef L2CACHE_SIZE
`define L2CACHE_SIZE 262144
`define L2CACHE_SIZE 131072
`endif
// Number of banks
@ -397,7 +397,7 @@
// Size of cache in bytes
`ifndef L3CACHE_SIZE
`define L3CACHE_SIZE 1048576
`define L3CACHE_SIZE 131072
`endif
// Number of banks

View file

@ -113,6 +113,8 @@ module VX_mem_unit # (
.clk (clk),
.reset (icache_reset),
.flush (1'b0),
// Core request
.core_req_valid (core_icache_req_if.valid),
.core_req_rw (core_icache_req_if.rw),
@ -170,6 +172,8 @@ module VX_mem_unit # (
.clk (clk),
.reset (dcache_reset),
.flush (1'b0),
// Core req
.core_req_valid (dcache_req_if.valid),
.core_req_rw (dcache_req_if.rw),

View file

@ -184,6 +184,8 @@ module Vortex (
.clk (clk),
.reset (reset),
.flush (1'b0),
`ifdef PERF_ENABLE
.perf_cache_if (perf_l3cache_if),
`endif

View file

@ -77,9 +77,10 @@ module VX_bank #(
input wire dram_req_ready,
// DRAM response
input wire dram_rsp_valid,
input wire [`LINE_ADDR_WIDTH-1:0] dram_rsp_addr,
input wire [`CACHE_LINE_WIDTH-1:0] dram_rsp_data,
input wire dram_rsp_valid,
input wire [`LINE_ADDR_WIDTH-1:0] dram_rsp_addr,
input wire [`CACHE_LINE_WIDTH-1:0] dram_rsp_data,
input wire dram_rsp_flush,
output wire dram_rsp_ready
);
@ -94,6 +95,7 @@ module VX_bank #(
wire drsq_empty, drsq_empty_next;
wire [`LINE_ADDR_WIDTH-1:0] drsq_addr_next;
wire [`CACHE_LINE_WIDTH-1:0] drsq_filldata_next;
wire drsq_flush_next;
wire drsq_push = dram_rsp_valid && dram_rsp_ready;
@ -101,7 +103,7 @@ module VX_bank #(
assign dram_rsp_ready = !drsq_full;
VX_fifo_queue_xt #(
.DATAW (`LINE_ADDR_WIDTH + $bits(dram_rsp_data)),
.DATAW (`LINE_ADDR_WIDTH + $bits(dram_rsp_data) + 1),
.SIZE (DRSQ_SIZE),
.FASTRAM (1)
) dram_rsp_queue (
@ -109,10 +111,10 @@ module VX_bank #(
.reset (reset),
.push (drsq_push),
.pop (drsq_pop),
.data_in ({dram_rsp_addr, dram_rsp_data}),
.data_in ({dram_rsp_addr, dram_rsp_data, dram_rsp_flush}),
`UNUSED_PIN (data_out),
.empty (drsq_empty),
.data_out_next ({drsq_addr_next, drsq_filldata_next}),
.data_out_next ({drsq_addr_next, drsq_filldata_next, drsq_flush_next}),
.empty_next (drsq_empty_next),
.full (drsq_full),
`UNUSED_PIN (almost_full),
@ -189,7 +191,7 @@ module VX_bank #(
wire [`CACHE_LINE_WIDTH-1:0] filldata_st0, filldata_st1;
wire [`REQS_BITS-1:0] req_tid_st0, req_tid_st1;
wire [`REQ_TAG_WIDTH-1:0] tag_st0, tag_st1;
wire valid_st0, valid_st1;
wire valid_st0, valid_st1;
wire is_fill_st0, is_fill_st1;
wire is_mshr_st0, is_mshr_st1;
wire [`CACHE_LINE_WIDTH-1:0] readdata_st1;
@ -201,6 +203,7 @@ module VX_bank #(
wire dreq_push_unqual_st0, dreq_push_unqual_st1;
wire writeen_st1;
wire core_req_hit_st1;
wire is_flush_st0;
wire mshr_push_stall;
wire crsq_push_stall;
@ -224,7 +227,7 @@ module VX_bank #(
assign is_fill_st0 = drsq_pop_unqual;
VX_pipe_register #(
.DATAW (`LINE_ADDR_WIDTH + `UP(`WORD_SELECT_BITS) + 1 + WORD_SIZE + `WORD_WIDTH + `REQS_BITS + `REQ_TAG_WIDTH + `CACHE_LINE_WIDTH),
.DATAW (`LINE_ADDR_WIDTH + `UP(`WORD_SELECT_BITS) + 1 + WORD_SIZE + `WORD_WIDTH + `REQS_BITS + `REQ_TAG_WIDTH + `CACHE_LINE_WIDTH + 1),
.RESETW (0)
) pipe_reg0 (
.clk (clk),
@ -238,9 +241,10 @@ module VX_bank #(
mshr_valid_next ? mshr_writeword_next : creq_writeword_next,
mshr_valid_next ? mshr_tid_next : creq_tid_next,
mshr_valid_next ? `REQ_TAG_WIDTH'(mshr_tag_next) : `REQ_TAG_WIDTH'(creq_tag_next),
drsq_filldata_next
drsq_filldata_next,
drsq_flush_next
}),
.data_out ({addr_st0, wsel_st0, mem_rw_st0, byteen_st0, writeword_st0, req_tid_st0, tag_st0, filldata_st0})
.data_out ({addr_st0, wsel_st0, mem_rw_st0, byteen_st0, writeword_st0, req_tid_st0, tag_st0, filldata_st0, is_flush_st0})
);
`ifdef DBG_CACHE_REQ_INFO
@ -267,15 +271,14 @@ module VX_bank #(
`ifdef DBG_CACHE_REQ_INFO
.debug_pc (debug_pc_st0),
.debug_wid (debug_wid_st0),
`endif
.stall (pipeline_stall),
`endif
// read/Fill
.lookup_in (creq_pop || mshr_pop),
.addr_in (addr_st0),
.do_fill_in (drsq_pop),
.miss_out (miss_st0)
.lookup (creq_pop || mshr_pop),
.addr (addr_st0),
.fill (drsq_pop),
.is_flush (is_flush_st0),
.missed (miss_st0)
);
// redundant fills
@ -337,21 +340,20 @@ module VX_bank #(
.debug_pc (debug_pc_st1),
.debug_wid (debug_wid_st1),
`endif
.stall (pipeline_stall),
.addr_in (addr_st1),
.addr (addr_st1),
// reading
.readen_in (valid_st1 && !mem_rw_st1 && !is_fill_st1),
.readdata_out (readdata_st1),
.readen (valid_st1 && !mem_rw_st1 && !is_fill_st1 && ~pipeline_stall),
.readdata (readdata_st1),
// writing
.writeen_in (valid_st1 && writeen_st1),
.wfill_in (is_fill_st1),
.wwsel_in (wsel_st1),
.wbyteen_in (byteen_st1),
.writeword_in (writeword_st1),
.filldata_in (filldata_st1)
.writeen (valid_st1 && writeen_st1 && ~pipeline_stall),
.is_fill (is_fill_st1),
.wsel (wsel_st1),
.byteen (byteen_st1),
.writeword (writeword_st1),
.filldata (filldata_st1)
);
`ifdef DBG_CACHE_REQ_INFO
@ -408,7 +410,7 @@ module VX_bank #(
.enqueue_almfull (mshr_almost_full),
// lookup
.lookup_ready (drsq_pop),
.lookup_ready (drsq_pop && !is_flush_st0),
.lookup_addr (addr_st0),
.lookup_match (mshr_pending_unqual_st0),
@ -559,7 +561,10 @@ module VX_bank #(
$display("%t: cache%0d:%0d pipeline-stall: mshr=%b, cwbq=%b, dwbq=%b", $time, CACHE_ID, BANK_ID, mshr_almost_full, crsq_push_stall, dreq_almost_full);
end
if (drsq_pop) begin
$display("%t: cache%0d:%0d fill-rsp: addr=%0h, data=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_st0, BANK_ID), filldata_st0);
if (is_flush_st0)
$display("%t: cache%0d:%0d flush: addr=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_st0, BANK_ID));
else
$display("%t: cache%0d:%0d fill-rsp: addr=%0h, data=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_st0, BANK_ID), filldata_st0);
end
if (creq_pop || mshr_pop) begin
if (mem_rw_st0)

View file

@ -4,7 +4,7 @@ module VX_cache #(
parameter CACHE_ID = 0,
// Size of cache in bytes
parameter CACHE_SIZE = 16384,
parameter CACHE_SIZE = 1048576,
// Size of line inside a bank in bytes
parameter CACHE_LINE_SIZE = 64,
// Number of banks
@ -46,6 +46,8 @@ module VX_cache #(
input wire clk,
input wire reset,
input wire flush,
// Core request
input wire [NUM_REQS-1:0] core_req_valid,
input wire [NUM_REQS-1:0] core_req_rw,
@ -114,7 +116,26 @@ module VX_cache #(
wire [NUM_BANKS-1:0] perf_write_miss_per_bank;
wire [NUM_BANKS-1:0] perf_mshr_stall_per_bank;
wire [NUM_BANKS-1:0] perf_pipe_stall_per_bank;
`endif
`endif
reg flush_enable;
reg [`LINE_SELECT_BITS-1:0] flush_ctr;
always @(posedge clk) begin
if (reset || flush) begin
flush_enable <= 1;
flush_ctr <= 0;
end else begin
if (flush_enable && (& per_bank_dram_rsp_ready)) begin
if (flush_addr == ((2 ** `LINE_SELECT_BITS)-1)) begin
flush_enable <= 0;
end
flush_ctr <= flush_ctr + 1;
end
end
end
wire [`LINE_ADDR_WIDTH-1:0] flush_addr = `LINE_ADDR_WIDTH'(flush_ctr);
VX_cache_core_req_bank_sel #(
.CACHE_LINE_SIZE (CACHE_LINE_SIZE),
@ -152,9 +173,9 @@ module VX_cache #(
assign dram_req_tag = dram_req_addr;
if (NUM_BANKS == 1) begin
`UNUSED_VAR (dram_rsp_tag)
assign dram_rsp_ready = per_bank_dram_rsp_ready;
assign dram_rsp_ready = per_bank_dram_rsp_ready && !flush_enable;
end else begin
assign dram_rsp_ready = per_bank_dram_rsp_ready[`DRAM_ADDR_BANK(dram_rsp_tag)];
assign dram_rsp_ready = per_bank_dram_rsp_ready[`DRAM_ADDR_BANK(dram_rsp_tag)] && !flush_enable;
end
for (genvar i = 0; i < NUM_BANKS; i++) begin
@ -183,6 +204,7 @@ module VX_cache #(
wire curr_bank_dram_rsp_valid;
wire [`LINE_ADDR_WIDTH-1:0] curr_bank_dram_rsp_addr;
wire [`CACHE_LINE_WIDTH-1:0] curr_bank_dram_rsp_data;
wire curr_bank_dram_rsp_flush;
wire curr_bank_dram_rsp_ready;
// Core Req
@ -216,13 +238,14 @@ module VX_cache #(
// DRAM response
if (NUM_BANKS == 1) begin
assign curr_bank_dram_rsp_valid = dram_rsp_valid;
assign curr_bank_dram_rsp_addr = dram_rsp_tag;
assign curr_bank_dram_rsp_valid = dram_rsp_valid || flush_enable;
assign curr_bank_dram_rsp_addr = flush_enable ? flush_addr : dram_rsp_tag;
end else begin
assign curr_bank_dram_rsp_valid = dram_rsp_valid && (`DRAM_ADDR_BANK(dram_rsp_tag) == i);
assign curr_bank_dram_rsp_addr = `DRAM_TO_LINE_ADDR(dram_rsp_tag);
assign curr_bank_dram_rsp_valid = (dram_rsp_valid && (`DRAM_ADDR_BANK(dram_rsp_tag) == i)) || flush_enable;
assign curr_bank_dram_rsp_addr = flush_enable ? flush_addr : `DRAM_TO_LINE_ADDR(dram_rsp_tag);
end
assign curr_bank_dram_rsp_data = dram_rsp_data;
assign curr_bank_dram_rsp_flush = flush_enable;
assign per_bank_dram_rsp_ready[i] = curr_bank_dram_rsp_ready;
VX_bank #(
@ -246,7 +269,7 @@ module VX_cache #(
`SCOPE_BIND_VX_cache_bank(i)
.clk (clk),
.reset (reset),
.reset (reset),
`ifdef PERF_ENABLE
.perf_read_misses (perf_read_miss_per_bank[i]),
@ -284,6 +307,7 @@ module VX_cache #(
.dram_rsp_valid (curr_bank_dram_rsp_valid),
.dram_rsp_addr (curr_bank_dram_rsp_addr),
.dram_rsp_data (curr_bank_dram_rsp_data),
.dram_rsp_flush (curr_bank_dram_rsp_flush),
.dram_rsp_ready (curr_bank_dram_rsp_ready)
);
end

View file

@ -28,32 +28,28 @@ module VX_data_access #(
`IGNORE_WARNINGS_END
`endif
input wire stall,
`IGNORE_WARNINGS_BEGIN
input wire[`LINE_ADDR_WIDTH-1:0] addr_in,
input wire[`LINE_ADDR_WIDTH-1:0] addr,
`IGNORE_WARNINGS_END
// reading
input wire readen_in,
output wire [`CACHE_LINE_WIDTH-1:0] readdata_out,
input wire readen,
output wire [`CACHE_LINE_WIDTH-1:0] readdata,
// writing
input wire writeen_in,
input wire [`UP(`WORD_SELECT_BITS)-1:0] wwsel_in,
input wire [WORD_SIZE-1:0] wbyteen_in,
input wire wfill_in,
input wire [`WORD_WIDTH-1:0] writeword_in,
input wire [`CACHE_LINE_WIDTH-1:0] filldata_in
input wire writeen,
input wire [`UP(`WORD_SELECT_BITS)-1:0] wsel,
input wire [WORD_SIZE-1:0] byteen,
input wire is_fill,
input wire [`WORD_WIDTH-1:0] writeword,
input wire [`CACHE_LINE_WIDTH-1:0] filldata
);
`UNUSED_VAR (reset)
wire [`CACHE_LINE_WIDTH-1:0] read_data;
wire [CACHE_LINE_SIZE-1:0] byte_enable;
wire [`CACHE_LINE_WIDTH-1:0] write_data;
wire write_enable;
wire [`LINE_SELECT_BITS-1:0] line_addr = addr_in[`LINE_SELECT_BITS-1:0];
wire [`LINE_SELECT_BITS-1:0] line_addr = addr[`LINE_SELECT_BITS-1:0];
VX_sp_ram #(
.DATAW(CACHE_LINE_SIZE * 8),
@ -63,48 +59,41 @@ module VX_data_access #(
) data_store (
.clk(clk),
.addr(line_addr),
.wren(write_enable),
.wren(writeen),
.byteen(byte_enable),
.rden(1'b1),
.din(write_data),
.dout(read_data)
.dout(readdata)
);
wire [`WORDS_PER_LINE-1:0][WORD_SIZE-1:0] wbyteen_qual;
wire [`WORDS_PER_LINE-1:0][`WORD_WIDTH-1:0] writedata_qual;
wire [`WORDS_PER_LINE-1:0][WORD_SIZE-1:0] byteen_qual;
if (`WORD_SELECT_BITS != 0) begin
for (genvar i = 0; i < `WORDS_PER_LINE; i++) begin
assign wbyteen_qual[i] = (wwsel_in == `WORD_SELECT_BITS'(i)) ? wbyteen_in : {WORD_SIZE{1'b0}};
assign writedata_qual[i] = writeword_in;
assign byteen_qual[i] = (wsel == `WORD_SELECT_BITS'(i)) ? byteen : {WORD_SIZE{1'b0}};
end
end else begin
`UNUSED_VAR (wwsel_in)
assign wbyteen_qual = wbyteen_in;
assign writedata_qual = writeword_in;
`UNUSED_VAR (wsel)
assign byteen_qual = byteen;
end
assign write_enable = writeen_in && !stall;
assign byte_enable = wfill_in ? {CACHE_LINE_SIZE{1'b1}} : wbyteen_qual;
assign write_data = wfill_in ? filldata_in : writedata_qual;
assign readdata_out = read_data;
assign byte_enable = is_fill ? {CACHE_LINE_SIZE{1'b1}} : byteen_qual;
assign write_data = is_fill ? filldata : {`WORDS_PER_LINE{writeword}};
`UNUSED_VAR (readen_in)
`UNUSED_VAR (readen)
`ifdef DBG_PRINT_CACHE_DATA
always @(posedge clk) begin
if (!stall) begin
if (writeen_in) begin
if (wfill_in) begin
$display("%t: cache%0d:%0d data-fill: addr=%0h, blk_addr=%0d, data=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), line_addr, write_data);
end else begin
$display("%t: cache%0d:%0d data-write: addr=%0h, wid=%0d, PC=%0h, byteen=%b, blk_addr=%0d, wsel=%0d, data=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), debug_wid, debug_pc, byte_enable, line_addr, wwsel_in, writeword_in);
end
end
if (readen_in) begin
$display("%t: cache%0d:%0d data-read: addr=%0h, wid=%0d, PC=%0h, blk_addr=%0d, data=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), debug_wid, debug_pc, line_addr, read_data);
end
end
always @(posedge clk) begin
if (writeen) begin
if (is_fill) begin
$display("%t: cache%0d:%0d data-fill: addr=%0h, blk_addr=%0d, data=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr, BANK_ID), line_addr, write_data);
end else begin
$display("%t: cache%0d:%0d data-write: addr=%0h, wid=%0d, PC=%0h, byteen=%b, blk_addr=%0d, wsel=%0d, data=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr, BANK_ID), debug_wid, debug_pc, byte_enable, line_addr, wsel, writeword);
end
end
if (readen) begin
$display("%t: cache%0d:%0d data-read: addr=%0h, wid=%0d, PC=%0h, blk_addr=%0d, data=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr, BANK_ID), debug_wid, debug_pc, line_addr, readdata);
end
end
`endif

View file

@ -25,23 +25,21 @@ module VX_tag_access #(
input wire[`NW_BITS-1:0] debug_wid,
`IGNORE_WARNINGS_END
`endif
input wire stall,
// read/fill
input wire lookup_in,
input wire[`LINE_ADDR_WIDTH-1:0] addr_in,
input wire do_fill_in,
output wire miss_out
input wire lookup,
input wire[`LINE_ADDR_WIDTH-1:0] addr,
input wire fill,
input wire is_flush,
output wire missed
);
`UNUSED_VAR (reset)
wire read_valid;
wire [`TAG_SELECT_BITS-1:0] read_tag;
wire do_fill;
wire [`TAG_SELECT_BITS-1:0] line_tag = `LINE_TAG_ADDR(addr_in);
wire [`LINE_SELECT_BITS-1:0] line_addr = addr_in [`LINE_SELECT_BITS-1:0];
wire [`TAG_SELECT_BITS-1:0] line_tag = `LINE_TAG_ADDR(addr);
wire [`LINE_SELECT_BITS-1:0] line_addr = addr [`LINE_SELECT_BITS-1:0];
VX_sp_ram #(
.DATAW(`TAG_SELECT_BITS + 1),
@ -51,34 +49,35 @@ module VX_tag_access #(
) tag_store (
.clk(clk),
.addr(line_addr),
.wren(do_fill),
.wren(fill),
.byteen(1'b1),
.rden(1'b1),
.din({1'b1, line_tag}),
.din({!is_flush, line_tag}),
.dout({read_valid, read_tag})
);
wire tags_match = read_valid && (line_tag == read_tag);
assign do_fill = do_fill_in && !stall;
assign missed = !tags_match;
assign miss_out = !tags_match;
wire do_lookup = lookup_in && !stall;
wire do_lookup = lookup;
`UNUSED_VAR (do_lookup)
`ifdef DBG_PRINT_CACHE_TAG
always @(posedge clk) begin
if (do_fill) begin
$display("%t: cache%0d:%0d tag-fill: addr=%0h, blk_addr=%0d, tag_id=%0h, old_tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), line_addr, line_tag, read_tag);
if (fill) begin
if (is_flush)
$display("%t: cache%0d:%0d tag-flush: addr=%0h, blk_addr=%0d", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr, BANK_ID), line_addr);
else
$display("%t: cache%0d:%0d tag-fill: addr=%0h, blk_addr=%0d, tag_id=%0h, old_tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr, BANK_ID), line_addr, line_tag, read_tag);
if (tags_match) begin
$display("%t: warning: redundant fill - addr=%0h", $time, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID));
$display("%t: warning: redundant fill - addr=%0h", $time, `LINE_TO_BYTE_ADDR(addr, BANK_ID));
end
end else if (do_lookup) begin
if (tags_match) begin
$display("%t: cache%0d:%0d tag-hit: addr=%0h, wid=%0d, PC=%0h, blk_addr=%0d, tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), debug_wid, debug_pc, line_addr, line_tag);
$display("%t: cache%0d:%0d tag-hit: addr=%0h, wid=%0d, PC=%0h, blk_addr=%0d, tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr, BANK_ID), debug_wid, debug_pc, line_addr, line_tag);
end else begin
$display("%t: cache%0d:%0d tag-miss: addr=%0h, wid=%0d, PC=%0h, blk_addr=%0d, tag_id=%0h, old_tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr_in, BANK_ID), debug_wid, debug_pc, line_addr, line_tag, read_tag);
$display("%t: cache%0d:%0d tag-miss: addr=%0h, wid=%0d, PC=%0h, blk_addr=%0d, tag_id=%0h, old_tag_id=%0h", $time, CACHE_ID, BANK_ID, `LINE_TO_BYTE_ADDR(addr, BANK_ID), debug_wid, debug_pc, line_addr, line_tag, read_tag);
end
end
end

View file

@ -55,7 +55,7 @@ smart.log: $(PROJECT_FILES)
# Project initialization
$(PROJECT_FILES):
quartus_sh -t ../project.tcl -project $(PROJECT) -family $(FAMILY) -device $(DEVICE) -top $(TOP_LEVEL_ENTITY) -src "$(SRC_FILE)" -sdc ../project.sdc -inc "$(RTL_INCLUDE)" -set "NOPAE" -set "NUM_CORES=8"
quartus_sh -t ../project.tcl -project $(PROJECT) -family $(FAMILY) -device $(DEVICE) -top $(TOP_LEVEL_ENTITY) -src "$(SRC_FILE)" -sdc ../project.sdc -inc "$(RTL_INCLUDE)" -set "NOPAE" -set "NUM_CORES=8" -set "L3_ENABLE=1"
syn.chg:
$(STAMP) syn.chg