litedram: Add an L2 cache with store queue

This adds a cache between the wishbone and litedram with the following
features (at this point, it's still evolving)

  - 128 bytes line width in order to have a reasonable amount of
litedram pipelining on the 128-bit wide data port.

  - Configurable geometry otherwise

  - Stores are acked immediately on wishbone whether hit or miss
(minus a 2 cycles delay if there's a previous load response in the
way) and sent to LiteDRAM via 8 entries (configurable) store queue

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
pull/190/head
Benjamin Herrenschmidt 4 years ago
parent bf1b98b958
commit a3857aac94

@ -50,7 +50,7 @@ core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \
loadstore1.vhdl mmu.vhdl dcache.vhdl writeback.vhdl core_debug.vhdl \ loadstore1.vhdl mmu.vhdl dcache.vhdl writeback.vhdl core_debug.vhdl \
core.vhdl core.vhdl


soc_files = wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl \ soc_files = wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \
wishbone_debug_master.vhdl xics.vhdl syscon.vhdl soc.vhdl wishbone_debug_master.vhdl xics.vhdl syscon.vhdl soc.vhdl


soc_sim_files = sim_console.vhdl sim_uart.vhdl sim_bram_helpers.vhdl \ soc_sim_files = sim_console.vhdl sim_uart.vhdl sim_bram_helpers.vhdl \

File diff suppressed because one or more lines are too long

@ -0,0 +1,84 @@
$ version 1.1

# Signals in entities :
/core_dram_tb/dram/rst
/core_dram_tb/dram/system_clk
/core_dram_tb/dram/system_reset
/core_dram_tb/dram/wb_in
/core_dram_tb/dram/wb_out
/core_dram_tb/dram/user_port0_cmd_valid
/core_dram_tb/dram/user_port0_cmd_ready
/core_dram_tb/dram/user_port0_cmd_we
/core_dram_tb/dram/user_port0_cmd_addr
/core_dram_tb/dram/user_port0_wdata_valid
/core_dram_tb/dram/user_port0_wdata_ready
/core_dram_tb/dram/user_port0_wdata_we
/core_dram_tb/dram/user_port0_wdata_data
/core_dram_tb/dram/user_port0_rdata_valid
/core_dram_tb/dram/user_port0_rdata_ready
/core_dram_tb/dram/user_port0_rdata_data
/core_dram_tb/dram/cache_tags
/core_dram_tb/dram/cache_valids
/core_dram_tb/dram/storeq_rd_ready
/core_dram_tb/dram/storeq_rd_valid
/core_dram_tb/dram/storeq_rd_data
/core_dram_tb/dram/storeq_wr_ready
/core_dram_tb/dram/storeq_wr_valid
/core_dram_tb/dram/storeq_wr_data
/core_dram_tb/dram/accept_store
/core_dram_tb/dram/state
/core_dram_tb/dram/wb_req
/core_dram_tb/dram/store_queued
/core_dram_tb/dram/read_ack_0
/core_dram_tb/dram/read_ack_1
/core_dram_tb/dram/read_ad3_0
/core_dram_tb/dram/read_ad3_1
/core_dram_tb/dram/read_way_0
/core_dram_tb/dram/read_way_1
/core_dram_tb/dram/req_index
/core_dram_tb/dram/req_row
/core_dram_tb/dram/req_hit_way
/core_dram_tb/dram/req_tag
/core_dram_tb/dram/req_op
/core_dram_tb/dram/req_laddr
/core_dram_tb/dram/req_ad3
/core_dram_tb/dram/req_we
/core_dram_tb/dram/req_wdata
/core_dram_tb/dram/store_way
/core_dram_tb/dram/store_index
/core_dram_tb/dram/store_row
/core_dram_tb/dram/cache_out
/core_dram_tb/dram/plru_victim
/core_dram_tb/dram/replace_way
/core_dram_tb/dram/rams/do_read
/core_dram_tb/dram/rams/do_write
/core_dram_tb/dram/rams/rd_addr
/core_dram_tb/dram/rams/wr_addr
/core_dram_tb/dram/rams/wr_data
/core_dram_tb/dram/rams/wr_sel
/core_dram_tb/dram/rams/wr_sel_m
/core_dram_tb/dram/rams/dout
/core_dram_tb/dram/rams/way/clk
/core_dram_tb/dram/rams/way/rd_en
/core_dram_tb/dram/rams/way/rd_addr
/core_dram_tb/dram/rams/way/rd_data
/core_dram_tb/dram/rams/way/wr_sel
/core_dram_tb/dram/rams/way/wr_addr
/core_dram_tb/dram/rams/way/wr_data
/core_dram_tb/dram/rams/way/rd_data0
/core_dram_tb/dram/store_queue/wr_ready
/core_dram_tb/dram/store_queue/wr_valid
/core_dram_tb/dram/store_queue/wr_data
/core_dram_tb/dram/store_queue/rd_ready
/core_dram_tb/dram/store_queue/rd_valid
/core_dram_tb/dram/store_queue/rd_data
/core_dram_tb/dram/store_queue/rd_idx
/core_dram_tb/dram/store_queue/rd_next
/core_dram_tb/dram/store_queue/wr_idx
/core_dram_tb/dram/store_queue/wr_next
/core_dram_tb/dram/store_queue/op_prev
/core_dram_tb/dram/store_queue/op_next
/core_dram_tb/dram/store_queue/full
/core_dram_tb/dram/store_queue/empty
/core_dram_tb/dram/store_queue/push
/core_dram_tb/dram/store_queue/pop

File diff suppressed because it is too large Load Diff

@ -9,9 +9,9 @@
#define CONFIG_CPU_NOP "nop" #define CONFIG_CPU_NOP "nop"


#ifdef __SIM__ #ifdef __SIM__
#define MEMTEST_BUS_SIZE 16 #define MEMTEST_BUS_SIZE 512//16
#define MEMTEST_DATA_SIZE 16 #define MEMTEST_DATA_SIZE 1024//16
#define MEMTEST_ADDR_SIZE 16 #define MEMTEST_ADDR_SIZE 128//16
#define CONFIG_SIM_DISABLE_DELAYS #define CONFIG_SIM_DISABLE_DELAYS
#endif #endif



File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-26 20:37:38 // Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-30 20:25:53
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
module litedram_core( module litedram_core(
input wire clk, input wire clk,

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-26 20:37:40 // Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-30 20:25:55
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
module litedram_core( module litedram_core(
input wire clk, input wire clk,

@ -510,7 +510,7 @@ a64b5a7d14004a39
0000000000000000 0000000000000000
0000000000000000 0000000000000000
0000000000000000 0000000000000000
384296003c4c0001 384297003c4c0001
fbc1fff07c0802a6 fbc1fff07c0802a6
f8010010fbe1fff8 f8010010fbe1fff8
3be10020f821fe91 3be10020f821fe91
@ -519,11 +519,11 @@ f8c101a838800140
38c101987c651b78 38c101987c651b78
7fe3fb78f8e101b0 7fe3fb78f8e101b0
f92101c0f90101b8 f92101c0f90101b8
48000da5f94101c8 48000d65f94101c8
7c7e1b7860000000 7c7e1b7860000000
480008bd7fe3fb78 4800087d7fe3fb78
3821017060000000 3821017060000000
480013647fc3f378 480013247fc3f378
0100000000000000 0100000000000000
4e80002000000280 4e80002000000280
0000000000000000 0000000000000000
@ -531,67 +531,67 @@ f92101c0f90101b8
4e8000204c00012c 4e8000204c00012c
0000000000000000 0000000000000000
3c4c000100000000 3c4c000100000000
7c0802a63842955c 7c0802a63842965c
7d800026fbe1fff8 7d800026fbe1fff8
91810008f8010010 91810008f8010010
480007b1f821ff91 48000771f821ff91
3c62ffff60000000 3c62ffff60000000
4bffff3538637de8 4bffff3538637ca8
548400023880ffff 548400023880ffff
7c8026ea7c0004ac 7c8026ea7c0004ac
3fe0c0003c62ffff 3fe0c0003c62ffff
63ff000838637e08 63ff000838637cc8
3c62ffff4bffff11 3c62ffff4bffff11
38637e287bff0020 38637ce87bff0020
7c0004ac4bffff01 7c0004ac4bffff01
73e900017fe0feea 73e900017fe0feea
3c62ffff41820010 3c62ffff41820010
4bfffee538637e40 4bfffee538637d00
4d80000073e90002 4d80000073e90002
3c62ffff41820010 3c62ffff41820010
4bfffecd38637e48 4bfffecd38637d08
4e00000073e90004 4e00000073e90004
3c62ffff41820010 3c62ffff41820010
4bfffeb538637e50 4bfffeb538637d10
3be2804860000000 3bff7fa03fe2ffff
4bfffea57fe3fb78 4bfffea57fe3fb78
3c80c00041920028 3c80c00041920028
7884002060840010 7884002060840010
7c8026ea7c0004ac 7c8026ea7c0004ac
7884b2823c62ffff 7884b2823c62ffff
4bfffe7d38637e58 4bfffe7d38637d18
3c80c000418e004c 3c80c000418e004c
7884002060840018 7884002060840018
7c8026ea7c0004ac 7c8026ea7c0004ac
788465023c62ffff 788465023c62ffff
4bfffe5538637e78 4bfffe5538637d38
608400303c80c000 608400303c80c000
7c0004ac78840020 7c0004ac78840020
3c62ffff7c8026ea 3c62ffff7c8026ea
38637e987884b282 38637d587884b282
3d20c0004bfffe31 3d20c0004bfffe31
7929002061290020 7929002061290020
7d204eea7c0004ac 7d204eea7c0004ac
3c62ffff3c80000f 3c62ffff3c80000f
38637eb860844240 38637d7860844240
4bfffe057c892392 4bfffe057c892392
4bfffdfd7fe3fb78 4bfffdfd7fe3fb78
3ca2ffff418e0028 3ca2ffff418e0028
3c62ffff3c82ffff 3c62ffff3c82ffff
38847ee838a57ed8 38847da838a57d98
4bfffddd38637ef0 4bfffddd38637db0
60000000480004c1 6000000048000481
3c62ffff41920020 3c62ffff41920020
4bfffdc538637f20 4bfffdc538637de0
8181000838210070 8181000838210070
480011807d818120 480011407d818120
38637f383c62ffff 38637df83c62ffff
3c80f0004bfffda9 3c80f0004bfffda9
6084400038a0ffff 6084400038a0ffff
7884002054a50422 7884002054a50422
480008553c604000 480008153c604000
3c62ffff60000000 3c62ffff60000000
4bfffd7d38637f58 4bfffd7d38637e18
e801001038210070 e801001038210070
ebe1fff881810008 ebe1fff881810008
7d8181207c0803a6 7d8181207c0803a6
@ -605,138 +605,130 @@ ebe1fff881810008
4e8000207d20572a 4e8000207d20572a
0000000000000000 0000000000000000
3c4c000100000000 3c4c000100000000
7c0802a63842930c 7c0802a63842940c
614a08003d40c010 614a08003d40c010
794a002039200001 794a002039200001
f821ffa1f8010010 f821ffa1f8010010
7d20572a7c0004ac 7d20572a7c0004ac
3862802860000000 38637f803c62ffff
600000004bfffce1 600000004bfffce1
e801001038210060 e801001038210060
4e8000207c0803a6 4e8000207c0803a6
0100000000000000 0100000000000000
3c4c000100000080 3c4c000100000080
7c0802a6384292b4 7c0802a6384293b4
6129000c3d204000 38637e303c62ffff
3fc0aaaa48000ffd f821ff7148000fc1
f821ff713f804000 600000004bfffca1
63deaaaa3fa04000 3d40aaaa39000080
639c00043fe04000 3d2040007d0903a6
93df000063bd0008 91490000614aaaaa
93dd000093dc0000 4200fff839290004
4bfffce993c90000 4bfffce93f60aaaa
813f000060000000 3fa0aaaa60000000
7d29f278815c0000 637baaaa3f82ffff
7d2900347f8af000 3be000003bc00000
692900015529d97e 3b9c7e4063bdaaaa
7fff07b43be90001 3d3e10007b7b0020
7d3f07b4409e0008 792917647fc407b4
7f89f000813d0000 7f85e80080a90000
3bff0001419e000c 3bff0001419e001c
3d2040007fff07b4 7f83e3787f66db78
812900006129000c 4bfffc257fff07b4
2f8aaaaa6d2a5555 3bde000160000000
3bff0001419e000c 409effc82bbe0080
3fc055557fff07b4 3d40555539000080
3d2040003fa04000 3d2040007d0903a6
3f80400063de5555 91490000614a5555
63bd000461290008 4200fff839290004
93dd000093dc0000 600000004bfffc65
3d20400093c90000 3f82ffff3fa05555
93c900006129000c 3bc000003f605555
600000004bfffc4d 3b9c7e6063bd5555
7f89f000813c0000 3d3e1000637b5555
3bff0001419e000c 792917647fc407b4
813d00007fff07b4 7f85e80080a90000
2f8a55556d2a5555 3bff0001419e001c
3bff0001419e000c 7f83e3787f66db78
3d2040007fff07b4 4bfffba57fff07b4
8129000061290008 3bde000160000000
2f8a55556d2a5555 409effc82bbe0080
3bff0001419e000c 419e001c2fbf0000
3d2040007fff07b4 38a001003c62ffff
812900006129000c 38637e807fe4fb78
2f8a55556d2a5555 600000004bfffb79
3bff0001419e0028 3fc2ffff3c62ffff
3c62ffff7fff07b4 3bde7ec038637ea8
7fe4fb7838a00100 600000004bfffb61
4bfffb5538637f70 3d20400039400100
4800000c60000000 390000017d4903a6
409effe02fbf0000 3929000439480001
3ce0802039000004 9149fffc79480020
60e700037d0903a6 4bfffba94200fff0
392000013d404000 3940010060000000
7928f84278e70020 7d4903a639200000
7d2900d0792907e0 3d09100038c00001
7d293838394a0004 7908176439460001
912afffc7d294278 794600207d2407b4
4bfffb794200ffe4 7f8a284080a80000
3900000460000000 7fc3f378419e0014
7d0903a63ce08020 600000004bfffaf9
3d40400060e70003 392900014bffff98
392000013bc00000 3c62ffff4200ffcc
7928f84278e70020 4bfffadd38637ee0
7d2900d0792907e0 3920002060000000
7d2942787d293838 7d2903a639400000
7f884840810a0000 794800203d2a1000
3bde0001419e000c 394a000139290002
394a00047fde07b4 9109000079291764
2fbe00004200ffd4 4bfffb214200ffe8
3c62ffff419e001c 3f82ffff60000000
7fc4f37838a00004 3bc000003ba00000
4bfffa9538637f98 3d3d10003b9c7ef8
3d20400060000000 792917647fa607b4
6129000839400000 5529043e81290008
914900003ba00000 7d2507b47f893000
394000013d204000 3bde0001419e001c
914900006129000c 7f83e3787cc43378
394000023d204000 4bfffa657fde07b4
9149000061290010 3bbd000160000000
394000033d204000 409effc02bbd0020
9149000061290014 419e001c2fbe0000
600000004bfffabd 38a000203c62ffff
3940000039200004 38637f187fc4f378
3d2a10007d2903a6 600000004bfffa39
8129000879291764 386000007ffff214
7f8950005529043e 409e00b02f9f0000
3bbd0001419e000c 38637f403c62ffff
394a00017fbd07b4 600000004bfffa19
2fbd00004200ffdc 394001007c9602a6
3c62ffff419e001c 7d4903a678840020
7fa4eb7838a00004 3d49100039200000
4bfff9f538637fc0 794a176479280020
7ffefa1460000000 910a000039290001
7fffea143bc00000 7ff602a64200ffec
409e00a42f9f0000 3fe0000c7c9f2050
38637fe83c62ffff 7fff239663ff8000
600000004bfff9d1 600000004bfffa45
3f8040007f5602a6 7d3602a67bff0020
639c00043f604000 7929002039000100
3fa0400039200001 3d4040007d0903a6
3fc0400093db0000 394a0004810a0000
63bd0008913c0000 7cb602a64200fff8
63de000c39200002 3ca0000c7d254850
39200003913d0000 3c62ffff60a58000
7ff602a6913e0000 7fe4fb787ca54b96
600000004bfff9fd 78a5032038637f50
815b00007d3602a6 600000004bfff981
815d0000815c0000 3821009038600001
7cb602a6815e0000 0000000048000cd8
7ca5485038803200 0000058001000000
7ca42b967d3fd050 384290583c4c0001
3c62ffff7c844b96 3c62ffff7c0802a6
788404a078a504a0 48000c6138637fa8
3bc0000138637ff8
600000004bfff941
7fc3f37838210090
0000000048000cd4
0000068001000000
38428f183c4c0001
600000007c0802a6
48000c6138628050
3f60c010f821ff71 3f60c010f821ff71
637b10003be00000 637b10003be00000
4bfff8f57b7b0020 4bfff9357b7b0020
7c0004ac60000000 7c0004ac60000000
3f40c0107fe0df2a 3f40c0107fe0df2a
7b5a0020635a1008 7b5a0020635a1008
@ -756,22 +748,22 @@ f821ff713f804000
7d20ef2a7c0004ac 7d20ef2a7c0004ac
7c0004ac39200002 7c0004ac39200002
3860000f7d20f72a 3860000f7d20f72a
7c0004ac4bfffb09 7c0004ac4bfffb49
392000037fe0ef2a 392000037fe0ef2a
7d20f72a7c0004ac 7d20f72a7c0004ac
4bfffaed3860000f 4bfffb2d3860000f
7c0004ac39200006 7c0004ac39200006
3b8000017d20ef2a 3b8000017d20ef2a
7f80f72a7c0004ac 7f80f72a7c0004ac
4bfffacd3860000f 4bfffb0d3860000f
7c0004ac39200920 7c0004ac39200920
7c0004ac7d20ef2a 7c0004ac7d20ef2a
3860000f7fe0f72a 3860000f7fe0f72a
392004004bfffab1 392004004bfffaf1
7d20ef2a7c0004ac 7d20ef2a7c0004ac
7fe0f72a7c0004ac 7fe0f72a7c0004ac
4bfffa9538600003 4bfffad538600003
4bfffb294bfffad5 4bfffb694bfffb15
4082001c2c230000 4082001c2c230000
7f80df2a7c0004ac 7f80df2a7c0004ac
7f80d72a7c0004ac 7f80d72a7c0004ac
@ -780,27 +772,27 @@ f821ff713f804000
4bffffec38600001 4bffffec38600001
0100000000000000 0100000000000000
3c4c000100000680 3c4c000100000680
3d20c00038428d94 3d20c00038428ed4
6129200060000000 6129200060000000
f92280b879290020 f922801079290020
612900203d20c000 612900203d20c000
7c0004ac79290020 7c0004ac79290020
3d40001c7d204eea 3d40001c7d204eea
7d295392614a2000 7d295392614a2000
394a0018e94280b8 394a0018e9428010
7c0004ac3929ffff 7c0004ac3929ffff
4e8000207d2057ea 4e8000207d2057ea
0000000000000000 0000000000000000
3c4c000100000000 3c4c000100000000
6000000038428d34 6000000038428e74
39290010e92280b8 39290010e9228010
7d204eea7c0004ac 7d204eea7c0004ac
4082ffe871290008 4082ffe871290008
e94280b85469063e e94280105469063e
7d2057ea7c0004ac 7d2057ea7c0004ac
000000004e800020 000000004e800020
0000000000000000 0000000000000000
38428cf03c4c0001 38428e303c4c0001
fbc1fff07c0802a6 fbc1fff07c0802a6
3bc3fffffbe1fff8 3bc3fffffbe1fff8
f821ffd1f8010010 f821ffd1f8010010
@ -874,7 +866,7 @@ f924000039290002
7c6307b43863ffe0 7c6307b43863ffe0
000000004e800020 000000004e800020
0000000000000000 0000000000000000
38428aa03c4c0001 38428be03c4c0001
3d2037367c0802a6 3d2037367c0802a6
612935347d908026 612935347d908026
65293332792907c6 65293332792907c6
@ -908,7 +900,7 @@ fbfd00007fe9fa14
4bfffff07d29f392 4bfffff07d29f392
0300000000000000 0300000000000000
3c4c000100000580 3c4c000100000580
7c0802a638428994 7c0802a638428ad4
f821ffb1480006e9 f821ffb1480006e9
7c7f1b78eb630000 7c7f1b78eb630000
7cbd2b787c9c2378 7cbd2b787c9c2378
@ -924,7 +916,7 @@ f821ffb1480006e9
4bffffb8f93f0000 4bffffb8f93f0000
0100000000000000 0100000000000000
3c4c000100000580 3c4c000100000580
7c0802a638428914 7c0802a638428a54
f821ffa148000661 f821ffa148000661
7c9b23787c7d1b78 7c9b23787c7d1b78
388000007ca32b78 388000007ca32b78
@ -955,16 +947,16 @@ e95d00009b270000
f95d0000394a0001 f95d0000394a0001
000000004bffffa8 000000004bffffa8
0000078001000000 0000078001000000
384288183c4c0001 384289583c4c0001
480005397c0802a6 480005397c0802a6
7c741b79f821fed1 7c741b79f821fed1
38600000f8610060 38600000f8610060
2fa4000041820068 2fa4000041820068
39210040419e0060 39210040419e0060
3ac4ffff60000000 3ac4ffff3e42ffff
f92100703b410020 f92100703b410020
3ae0000060000000 3ae0000060000000
3a428068392280b0 3a527fc039228008
f92100783ba10060 f92100783ba10060
ebc1006089250000 ebc1006089250000
419e00102fa90000 419e00102fa90000
@ -1196,16 +1188,35 @@ e8010010ebc1fff0
20676e69746f6f42 20676e69746f6f42
415244206d6f7266 415244206d6f7266
0000000a2e2e2e4d 0000000a2e2e2e4d
20747365746d656d
000a2e2e2e737562
7830203a7375625b
7830203a5d783025
2073762078383025
000a783830257830
257830207375625b
257830203a5d7830
3020737620783830
00000a7838302578
20747365746d654d 20747365746d654d
6c69616620737562 6c69616620737562
252f6425203a6465 252f6425203a6465
73726f7272652064 73726f7272652064
000000000000000a 000000000000000a
20747365746d654d 20747365746d656d
6961662061746164 0a2e2e2e61746164
2f6425203a64656c 0000000000000000
726f727265206425 783020617461645b
0000000000000a73 7830203a5d783025
2073762078383025
000a783830257830
20747365746d656d
0a2e2e2e72646461
0000000000000000
783020726464615b
7830203a5d783025
2073762078383025
000a783830257830
20747365746d654d 20747365746d654d
6961662072646461 6961662072646461
2f6425203a64656c 2f6425203a64656c

@ -1,5 +1,5 @@
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-26 20:37:42 // Auto-generated by Migen (0d16e03) & LiteX (564d731a) on 2020-05-30 20:25:57
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
module litedram_core( module litedram_core(
input wire clk, input wire clk,

@ -48,6 +48,7 @@ filesets:
- soc.vhdl - soc.vhdl
- xics.vhdl - xics.vhdl
- syscon.vhdl - syscon.vhdl
- sync_fifo.vhdl
file_type : vhdlSource-2008 file_type : vhdlSource-2008


fpga: fpga:

@ -0,0 +1,163 @@
-- Synchronous FIFO with a protocol similar to AXI
--
-- The outputs are generated combinationally from the inputs
-- in order to allow for back-to-back transfers with the type
-- of flow control used by busses lite AXI, pipelined WB or
-- LiteDRAM native port when the FIFO is full.
--
-- That means that care needs to be taken by the user not to
-- generate the inputs combinationally from the outputs otherwise
-- it would create a logic loop.
--
-- If breaking that loop is required, a stash buffer could be
-- added to break the flow control "loop" between the read and
-- the write port.
--
library ieee;
use ieee.std_logic_1164.all;

library work;
use work.utils.all;

entity sync_fifo is
generic(
-- Fifo depth in entries
DEPTH : natural := 64;

-- Fifo width in bits
WIDTH : natural := 32;

-- When INIT_ZERO is set, the memory is pre-initialized to 0's
INIT_ZERO : boolean := false
);
port(
-- Control lines:
clk : in std_ulogic;
reset : in std_ulogic;

-- Write port
wr_ready : out std_ulogic;
wr_valid : in std_ulogic;
wr_data : in std_ulogic_vector(WIDTH - 1 downto 0);

-- Read port
rd_ready : in std_ulogic;
rd_valid : out std_ulogic;
rd_data : out std_ulogic_vector(WIDTH - 1 downto 0)
);
end entity sync_fifo;

architecture behaviour of sync_fifo is

subtype data_t is std_ulogic_vector(WIDTH - 1 downto 0);
type memory_t is array(0 to DEPTH - 1) of data_t;

function init_mem return memory_t is
variable m : memory_t;
begin
if INIT_ZERO then
for i in 0 to DEPTH - 1 loop
m(i) := (others => '0');
end loop;
end if;
return m;
end function;

signal memory : memory_t := init_mem;

subtype index_t is integer range 0 to DEPTH - 1;
signal rd_idx : index_t;
signal rd_next : index_t;
signal wr_idx : index_t;
signal wr_next : index_t;

function next_index(idx : index_t) return index_t is
variable r : index_t;
begin
if ispow2(DEPTH) then
r := (idx + 1) mod DEPTH;
else
r := idx + 1;
if r = DEPTH then
r := 0;
end if;
end if;
return r;
end function;
type op_t is (OP_POP, OP_PUSH);
signal op_prev : op_t := OP_POP;
signal op_next : op_t;

signal full, empty : std_ulogic;
signal push, pop : std_ulogic;
begin

-- Current state at last clock edge
empty <= '1' when rd_idx = wr_idx and op_prev = OP_POP else '0';
full <= '1' when rd_idx = wr_idx and op_prev = OP_PUSH else '0';

-- We can accept new data if we aren't full or we are but
-- the read port is going to accept data this cycle
wr_ready <= rd_ready or not full;

-- We can provide data if we aren't empty or we are but
-- the write port is going to provide data this cycle
rd_valid <= wr_valid or not empty;

-- Internal control signals
push <= wr_ready and wr_valid;
pop <= rd_ready and rd_valid;

-- Next state
rd_next <= next_index(rd_idx) when pop = '1' else rd_idx;
wr_next <= next_index(wr_idx) when push = '1' else wr_idx;
with push & pop select op_next <=
OP_PUSH when "10",
OP_POP when "01",
op_prev when others;

-- Read port output
rd_data <= memory(rd_idx) when empty = '0' else wr_data;

-- Read counter
reader: process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
rd_idx <= 0;
else
rd_idx <= rd_next;
end if;
end if;
end process;

-- Write counter and memory write
producer: process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
wr_idx <= 0;
else
wr_idx <= wr_next;

if push = '1' then
memory(wr_idx) <= wr_data;
end if;
end if;
end if;
end process;

-- Previous op latch used for generating empty/full
op: process(clk)
begin
if rising_edge(clk) then
if reset = '1' then
op_prev <= OP_POP;
else
op_prev <= op_next;
end if;
end if;
end process;

end architecture behaviour;
Loading…
Cancel
Save