diff options
| author | Julian Blake Kongslie | 2022-06-05 15:34:23 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2022-06-05 15:42:26 -0700 |
| commit | 9ce65b7d3573d92e1d98a13b58a5d5763ba073c5 (patch) | |
| tree | 7486552ff9428dcb76e22593f445a657b121f443 | |
| parent | SMC micro. (diff) | |
| download | multipdp8-9ce65b7d3573d92e1d98a13b58a5d5763ba073c5.tar.xz | |
Working L1 cache.
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | hdl/defs.svh | 2 | ||||
| -rw-r--r-- | hdl/fifo.sv | 4 | ||||
| -rw-r--r-- | hdl/mem_cache.sv | 108 | ||||
| -rw-r--r-- | hdl/top.sv | 51 | ||||
| -rw-r--r-- | tcl/init.tcl | 1 |
6 files changed, 158 insertions, 11 deletions
| @@ -1,6 +1,5 @@ | |||
| 1 | SOURCES := $(wildcard hdl/**.sv) | 1 | SOURCES := $(wildcard hdl/**.sv) |
| 2 | HEADERS := $(wildcard hdl/**.svh) | 2 | HEADERS := $(wildcard hdl/**.svh) |
| 3 | MEMORIES := $(addprefix build/, $(addsuffix .hex, $(basename $(wildcard mem/**.pal)))) | ||
| 4 | QUARTUS := $(shell find altera tcl -name \*.cdf -o -name \*.sdc -o -name \*.tcl) | 3 | QUARTUS := $(shell find altera tcl -name \*.cdf -o -name \*.sdc -o -name \*.tcl) |
| 5 | 4 | ||
| 6 | fpga: pdp8.sof | 5 | fpga: pdp8.sof |
| @@ -75,7 +74,7 @@ build/%.bin: %.pal | |||
| 75 | palbart $< | 74 | palbart $< |
| 76 | mv -f $*.bin $*.lst $(dir $@) | 75 | mv -f $*.bin $*.lst $(dir $@) |
| 77 | 76 | ||
| 78 | pdp8.sof: $(SOURCES) $(HEADERS) $(MEMORIES) $(QUARTUS) | 77 | pdp8.sof: $(SOURCES) $(HEADERS) $(QUARTUS) |
| 79 | [ ! -e pdp8.qpf ] || quartus_sh -t tcl/clean.tcl | 78 | [ ! -e pdp8.qpf ] || quartus_sh -t tcl/clean.tcl |
| 80 | quartus_sh -t tcl/init.tcl | 79 | quartus_sh -t tcl/init.tcl |
| 81 | quartus_sh --flow compile pdp8.qpf | 80 | quartus_sh --flow compile pdp8.qpf |
diff --git a/hdl/defs.svh b/hdl/defs.svh index f4590c8..f8b1032 100644 --- a/hdl/defs.svh +++ b/hdl/defs.svh | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | `define PDP_ADDRESS_BITS 15 | 6 | `define PDP_ADDRESS_BITS 15 |
| 7 | 7 | ||
| 8 | `define NUM_PDPS 16 | 8 | `define NUM_PDPS 1 |
| 9 | 9 | ||
| 10 | `define UART_BYTE_BITS 8 | 10 | `define UART_BYTE_BITS 8 |
| 11 | 11 | ||
diff --git a/hdl/fifo.sv b/hdl/fifo.sv index 19877c4..9399006 100644 --- a/hdl/fifo.sv +++ b/hdl/fifo.sv | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | module fifo | 1 | module fifo |
| 2 | #( WIDTH_BITS = 1 | 2 | #( WIDTH_BITS = 1 |
| 3 | , DEPTH_BITS = 10 | 3 | , DEPTH_BITS = 8 |
| 4 | ) | 4 | ) |
| 5 | ( input bit clock_in | 5 | ( input bit clock_in |
| 6 | , input bit clock_out | 6 | , input bit clock_out |
| @@ -21,7 +21,7 @@ module fifo | |||
| 21 | typedef bit [DEPTH_BITS-1:0] addr_t; | 21 | typedef bit [DEPTH_BITS-1:0] addr_t; |
| 22 | typedef bit [DEPTH_BITS:0] grey_t; | 22 | typedef bit [DEPTH_BITS:0] grey_t; |
| 23 | 23 | ||
| 24 | data_t data [DEPTH-1:0]; | 24 | (* ramstyle = "no_rw_check, M9K" *) data_t data [DEPTH-1:0]; |
| 25 | 25 | ||
| 26 | addr_t oldest, youngest; | 26 | addr_t oldest, youngest; |
| 27 | bit oldest_wrap, youngest_wrap; | 27 | bit oldest_wrap, youngest_wrap; |
diff --git a/hdl/mem_cache.sv b/hdl/mem_cache.sv new file mode 100644 index 0000000..5f3db73 --- /dev/null +++ b/hdl/mem_cache.sv | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | `include "defs.svh" | ||
| 2 | |||
| 3 | module mem_cache | ||
| 4 | #( SET_BITS = 8 | ||
| 5 | ) | ||
| 6 | ( input bit clock | ||
| 7 | , input bit reset | ||
| 8 | |||
| 9 | , output bit core_command_ready | ||
| 10 | , input bit core_command_valid | ||
| 11 | , input pdp_command_t core_command_data | ||
| 12 | |||
| 13 | , input bit ram_command_ready | ||
| 14 | , output bit ram_command_valid | ||
| 15 | , output pdp_command_t ram_command_data | ||
| 16 | |||
| 17 | , output bit ram_response_ready | ||
| 18 | , input bit ram_response_valid | ||
| 19 | , input pdp_read_response_t ram_response_data | ||
| 20 | |||
| 21 | , input bit core_response_ready | ||
| 22 | , output bit core_response_valid | ||
| 23 | , output pdp_read_response_t core_response_data | ||
| 24 | ); | ||
| 25 | |||
| 26 | localparam ADDRESS_TAG_LO = $clog2(`RAM_LINE_WORDS)+SET_BITS; | ||
| 27 | |||
| 28 | typedef bit [`PDP_ADDRESS_BITS-1:ADDRESS_TAG_LO] address_tag_t; | ||
| 29 | typedef bit [ADDRESS_TAG_LO-1:$clog2(`RAM_LINE_WORDS)] set_t; | ||
| 30 | |||
| 31 | typedef struct packed { | ||
| 32 | bit valid; | ||
| 33 | address_tag_t address; | ||
| 34 | } tag_t; | ||
| 35 | |||
| 36 | typedef struct packed { | ||
| 37 | tag_t tag; | ||
| 38 | ram_line_t data; | ||
| 39 | } cache_entry_t; | ||
| 40 | |||
| 41 | (* ramstyle = "no_rw_check, M9K" *) cache_entry_t cache [(1<<SET_BITS)-1:0]; | ||
| 42 | |||
| 43 | bit outstanding_fill; | ||
| 44 | |||
| 45 | bit [SET_BITS:0] reset_entry; | ||
| 46 | |||
| 47 | always @(posedge clock) begin | ||
| 48 | if (reset) begin | ||
| 49 | core_command_ready = 0; | ||
| 50 | ram_command_valid = 0; | ||
| 51 | ram_response_ready = 0; | ||
| 52 | core_response_valid = 0; | ||
| 53 | outstanding_fill = 0; | ||
| 54 | reset_entry = 0; | ||
| 55 | end else if (reset_entry < (1<<SET_BITS)) begin | ||
| 56 | cache[reset_entry] = 0; | ||
| 57 | ++reset_entry; | ||
| 58 | end else begin | ||
| 59 | if (ram_command_ready && ram_command_valid) | ||
| 60 | ram_command_valid = 0; | ||
| 61 | if (core_response_ready && core_response_valid) | ||
| 62 | core_response_valid = 0; | ||
| 63 | |||
| 64 | if (ram_response_ready && ram_response_valid) begin | ||
| 65 | automatic address_tag_t tag; | ||
| 66 | automatic set_t set; | ||
| 67 | automatic cache_entry_t entry; | ||
| 68 | {tag, set} = ram_response_data.address; | ||
| 69 | entry.tag.valid = 1; | ||
| 70 | entry.tag.address = tag; | ||
| 71 | entry.data = ram_response_data.data; | ||
| 72 | cache[set] = entry; | ||
| 73 | core_response_valid = 1; | ||
| 74 | core_response_data = ram_response_data; | ||
| 75 | outstanding_fill = 0; | ||
| 76 | end else if (core_command_ready && core_command_valid) begin | ||
| 77 | automatic address_tag_t tag; | ||
| 78 | automatic set_t set; | ||
| 79 | {tag, set} = core_command_data.address; | ||
| 80 | if (core_command_data.write) begin | ||
| 81 | automatic cache_entry_t entry; | ||
| 82 | entry.tag.valid = 1; | ||
| 83 | entry.tag.address = tag; | ||
| 84 | // FIXME masked stores | ||
| 85 | entry.data = core_command_data.data; | ||
| 86 | cache[set] = entry; | ||
| 87 | ram_command_valid = 1; | ||
| 88 | ram_command_data = core_command_data; | ||
| 89 | end else begin | ||
| 90 | automatic cache_entry_t entry = cache[set]; | ||
| 91 | if (entry.tag.valid && entry.tag.address == tag) begin | ||
| 92 | core_response_valid = 1; | ||
| 93 | core_response_data.address = {tag, set}; | ||
| 94 | core_response_data.data = entry.data; | ||
| 95 | end else begin | ||
| 96 | ram_command_valid = 1; | ||
| 97 | ram_command_data = core_command_data; | ||
| 98 | outstanding_fill = 1; | ||
| 99 | end | ||
| 100 | end | ||
| 101 | end | ||
| 102 | |||
| 103 | core_command_ready = !ram_command_valid && !core_response_valid && !outstanding_fill; | ||
| 104 | ram_response_ready = !core_response_valid; | ||
| 105 | end | ||
| 106 | end | ||
| 107 | |||
| 108 | endmodule | ||
| @@ -470,6 +470,45 @@ module top | |||
| 470 | bit rx_valid; | 470 | bit rx_valid; |
| 471 | uart_byte_t rx_data; | 471 | uart_byte_t rx_data; |
| 472 | 472 | ||
| 473 | bit cache_command_ready; | ||
| 474 | bit cache_command_valid; | ||
| 475 | pdp_command_t cache_command_data; | ||
| 476 | |||
| 477 | bit cache_response_ready; | ||
| 478 | bit cache_response_valid; | ||
| 479 | pdp_read_response_t cache_response_data; | ||
| 480 | |||
| 481 | `ifdef NO_L1_CACHE | ||
| 482 | assign cache_command_ready = pdp_command_ready[i]; | ||
| 483 | assign pdp_command_valid[i] = cache_command_valid; | ||
| 484 | assign pdp_command_data[i] = cache_command_data; | ||
| 485 | |||
| 486 | assign pdp_response_ready[i] = cache_response_ready; | ||
| 487 | assign cache_response_valid = pdp_response_valid[i]; | ||
| 488 | assign cache_response_data = pdp_response_data[i]; | ||
| 489 | `else | ||
| 490 | mem_cache cache | ||
| 491 | ( .clock(internal_clock) | ||
| 492 | , .reset(internal_reset) | ||
| 493 | |||
| 494 | , .core_command_ready(cache_command_ready) | ||
| 495 | , .core_command_valid(cache_command_valid) | ||
| 496 | , .core_command_data(cache_command_data) | ||
| 497 | |||
| 498 | , .ram_command_ready(pdp_command_ready[i]) | ||
| 499 | , .ram_command_valid(pdp_command_valid[i]) | ||
| 500 | , .ram_command_data(pdp_command_data[i]) | ||
| 501 | |||
| 502 | , .ram_response_ready(pdp_response_ready[i]) | ||
| 503 | , .ram_response_valid(pdp_response_valid[i]) | ||
| 504 | , .ram_response_data(pdp_response_data[i]) | ||
| 505 | |||
| 506 | , .core_response_ready(cache_response_ready) | ||
| 507 | , .core_response_valid(cache_response_valid) | ||
| 508 | , .core_response_data(cache_response_data) | ||
| 509 | ); | ||
| 510 | `endif | ||
| 511 | |||
| 473 | core cpu | 512 | core cpu |
| 474 | ( .clk(internal_clock) | 513 | ( .clk(internal_clock) |
| 475 | , .reset(internal_reset) | 514 | , .reset(internal_reset) |
| @@ -482,13 +521,13 @@ module top | |||
| 482 | , .uart_rx_valid(rx_valid) | 521 | , .uart_rx_valid(rx_valid) |
| 483 | , .uart_rx_data(rx_data) | 522 | , .uart_rx_data(rx_data) |
| 484 | 523 | ||
| 485 | , .mem_command_ready(pdp_command_ready[i]) | 524 | , .mem_command_ready(cache_command_ready) |
| 486 | , .mem_command_valid(pdp_command_valid[i]) | 525 | , .mem_command_valid(cache_command_valid) |
| 487 | , .mem_command(pdp_command_data[i]) | 526 | , .mem_command(cache_command_data) |
| 488 | 527 | ||
| 489 | , .mem_read_ready(pdp_response_ready[i]) | 528 | , .mem_read_ready(cache_response_ready) |
| 490 | , .mem_read_valid(pdp_response_valid[i]) | 529 | , .mem_read_valid(cache_response_valid) |
| 491 | , .mem_read(pdp_response_data[i]) | 530 | , .mem_read(cache_response_data) |
| 492 | 531 | ||
| 493 | , .switch_df(0) | 532 | , .switch_df(0) |
| 494 | , .switch_if(0) | 533 | , .switch_if(0) |
diff --git a/tcl/init.tcl b/tcl/init.tcl index 9c94592..4e4660d 100644 --- a/tcl/init.tcl +++ b/tcl/init.tcl | |||
| @@ -5,6 +5,7 @@ set_global_assignment -name DEVICE 10CL025YU256I7G | |||
| 5 | set_global_assignment -name TOP_LEVEL_ENTITY top | 5 | set_global_assignment -name TOP_LEVEL_ENTITY top |
| 6 | set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 | 6 | set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 |
| 7 | set_global_assignment -name VERILOG_MACRO "SYNTHESIS=1" | 7 | set_global_assignment -name VERILOG_MACRO "SYNTHESIS=1" |
| 8 | #set_global_assignment -name VERILOG_MACRO "NO_L1_CACHE=1" | ||
| 8 | set_global_assignment -name NUM_PARALLEL_PROCESSORS 1 | 9 | set_global_assignment -name NUM_PARALLEL_PROCESSORS 1 |
| 9 | set_global_assignment -name ENABLE_SIGNALTAP OFF | 10 | set_global_assignment -name ENABLE_SIGNALTAP OFF |
| 10 | 11 | ||
