From 85753b2a740aeb1f983d14a0eab49698a9586dc6 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:26:42 +0100 Subject: [PATCH 1/6] [figures] update Wishbone bus examples --- docs/figures/wishbone_classic_read.png | Bin 24720 -> 20153 bytes docs/figures/wishbone_pipelined_write.png | Bin 26386 -> 21838 bytes docs/sources/wishbone_classic_read.json | 2 -- docs/sources/wishbone_pipelined_write.json | 2 -- 4 files changed, 4 deletions(-) diff --git a/docs/figures/wishbone_classic_read.png b/docs/figures/wishbone_classic_read.png index 8128f04dfac95897d074aa24d734d43eeb335455..002c9bcfe1d9cb2d847ae78b06f3732e33f1ff45 100644 GIT binary patch literal 20153 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

=KVwnSESxG7{$zhu3o(hC4M^<9b*So8E3av*gh; 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 literal 24720 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 diff --git a/docs/figures/wishbone_pipelined_write.png b/docs/figures/wishbone_pipelined_write.png index ac84461704f3d0a52c569678933500a512ba2e85..df3dedd0f7284985841089f0ccaa69c53803908a 100644 GIT binary patch literal 21838 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 literal 26386 zcma%jWmr|)+V)&@h;#_j-O@^jbcrZk(hY)iEJC`wq@+Z;K~khcO6g7!knRQRo4EHr zXP@_+_q-pM{6MZb$6%~6$8$e-%&=!FvRD|T7ytlZ$;&-`4gip4@Y@m%1^k~F0VXN{ zpaSHdO1yA4*lUHpAe?IIy&0Wm*#c0SOkeHFpp9*c9HR zj8p9-U)l5YTQW<^)39Q$ct?GR{0^D%d%98G&*^QgIXR;q$nO3wWep?JfdvbKklU~MHnYLxy+S92 z^?O&nliYpSmsPk%gHeYT9KO`Hzl`h`kqmqCIa9j;cd$tKy#e_Qga2y7rM` z&WBPEa~tfTD5O{bPaHu`93Mhpq&)oyAN)b$Db>u1i{l76A)$-CrR5KU=-?PcaTHFkACzSB>lT8(tyWf6JSy)V z<4OyceEb+dZ0KEeyxJYXtRvig_FZyMgQDhmtu;6rVTg#+bG;1$2+tw!Rn_4gVH*2R z6e>55&ClOUOG}evCuY~-9UB{~x(Dd+YLKl-(>_+^uQ@g;$)pn)iOwo9;paC$1D?XC z1Mn}?LJZ&N>CJ1lwzdYy1_lOJ8hs9^+4`CpVd027mja;xQZp%a_n!GR9Zh^mok7I8 zF|l!3x1jL#h!H;On`^(>b3l&y`SWMahYvr#fJ4fX=yjc$`B}I^Hd|$)XpQQP#%Ki= zJ8WOXQ68yFQ*m=wSG|9~DjO6OBzZMIujl6DbK?v=D;x0hrim0oaW^M6(nB=2(YtZ7 zc-I0ci(sU*?1HNr(kynI40Sz;y}O6eY^_zEh=|BaRaKSbRcL5v7^`ME9Uz{~g2>eI z)^FjLK=5cI4{Nla$I4U4q{6tpz@te`n|!6swQf$U$x>}QL_|c~E=xBz0aH^`JrW9v ztnN(;0eFl3!AH(n6I(5j>OA21eK9DW0|Vo>9tyuD26FH&)o?3cLW68NUQ~VNs(R;lg{N<&bGka{96oGMOIpgA z?bsk4BIt8N7!mAgu#+k;bvssNzEq=umW-46Ikc!>Z+)a&(#}SEiIDBs3-|1C#R*E8VgFmkIU1!VWZ>B z2+`8j*S0QUT?V2Np&kLSZp3lU?LtCti=!Uc8rFRMkx$3KKq2J3sr2}DWnLa)GKcqYv@ zFMbXxU#IQtgm(^%i7;GFQ``Y1;x%qp7MElY4w1My6G5V$(>7= zf6M=hd82iKy2YQ5Z**7*e9kZFADQ$-V!Q6mCM9HNbLQ*TStnf|tbEz&H@D<}!_>jQ z+?yNTptMX-tMjfA9aFZ{+N2vQ=q+xv);Gk-&3)u;W3w}qpHKHW0bB(`3K9}I#tOum zreFkHMBj%WLlH``Xxf6`s@u-e^m41)@~28hVPRwMKOiU1lp!sssKCahYg%15zK8r4i}py$R}_6Hji=~5FGe&xB08FAysNkO z3;5^lQ)eTZ|8-Fq!Vn>ytO*m9?IZAsJeH>7p{Fmn{8p^qdF7y}h{>i~e~*EI!TtWz zN4EiwZym8x%U&yIUw=lWw7prQgr|NU8`A)^ItLA2y!e&^9(vC1Gqethc~B+ZxNHUQ zrQ5RxA>Xr_Y<4yl7Cfi?q9W|Nx;lLt#8*iS1PLoQxuJay2sOuE2cJ=6j(4*?L@%r2 zdgtW;bSg+D+EZz1yXdg6nZ?CL(eK-DI)5!RGb$)5dX*crej)+p1qma}fFOHn+cCSNGpb zN~u2I$>J{3Gr!>}$#o{75?C~12RA@M{A4#YCi~LEVL!;L>^b_$#3B+AhaMU^IXS}H zj~`j4>+Q(yVPPTDC(AIRpG&TyF(x2V?5%KY(sf!L*x2FGL{zoNt87H^!5BC>7WBL#eIuFP;%LP0XHem8{)#1wG1#58uwuvsv2RG;NaV%KI(3uc5(UTl)_wC@6I4KRT9ey{Qz4bYD(6 z;q=57{m_*XTH7Z!%oTtzgq&F}^C4&~wCE-97#(mx>`>ywDsuiQ=XOpuvERJEnVl&9 zdN0QVlVMifTC{to&~E9|Cyk5cz{LtOGWapa^N3HM1T8Jy@kvSfSv3Y!5hf<5){d3o zZ5OKubo3(5Gka|eS!JI9VBLF{Qy6>3Ga^ULhrI40{7NhNqLH05+OH{h-MsIE-#49K zMSyr=zAB{SePd(VaBC~y1hb`9;g|Ox658{%4EbZ{FUs_7eO*Fs&HfrlGr4!5w&Bz=ATZW^y^z|VVpuSmU6Y38yMb0))e z_hQQ7+4A!2D{U)`*nl{W01CYLf*+kxWXj=I1bC_SK6!alos8M3OPanE4!&t)d|kKmC+@pdt;e>Wrq z@X#EcbVa-WP^*G`*;HllFd}k@9Gp4h1a(M%h87!wSzb%&YnpZJ7GN++?&fCLD+)Gs ztu92*{#EM8^Z4?rd8)0JZC0%|-e;q*CjKIRDzEQrf9Us;6xczgTb3J(=6*dv@=hhw z4x_UD?9~8z<(qUJL3;K!m2wZ;&>h=>E76-1Q8^`;C;_pm%BJwmiF#}*2|{=GN4NcJ z3`F%w&GlXK+cNFrh^j!;7&sBo2`n?VB$qH1Rw?rhygbDDJdHd*VBZ2nAZxIdK3_>{ zE<_1@A)G`3tdB=@>lQ1~Ut?TiVqh3lfFDi~kh-~GSj8y{^Kuc>o5OV|6^0pCm9u;4fQh6xLni*8p~50Fw@;cGq`F3ZTN zPh+(5*O9b-eR}-UQYPPe{HJ~vDW&k~V1NImnUvHQm1xymJpt;WY%!>VrY3P(5kBR; z>idAf#m|yJ9CC7rIkD90!271Ca+pf-S!7~-HXX)eFYzp6vgcuI^c^N9__0ZKnCa=a zn4O)SMz*&1s;h6&)6@ASw5E9rH!I%**!QD5Mb2X-m|_&FU+F>x`^qmDlQMKkTrH4Muq{9UQc!vLu-u#GRb)`5b4sC6Nm^GLQej ztt6aUCUG#gN7%B#nx5jV#YGs(^AQr%tMt7Q8vX8~Bd!{qtJm&J{>CNlMs`TdelNEd zG4i2UKiWlmp!?5MH|W4awjPYiitQEg7&%1!tWV}^jiqhErgs0vE%i=@9d(1Y$@oD39WyzyvH=ur%Am_Op zv)p0r^*_7$T zHO5(F9liuz7UmrIafJ{ zzuE*d?*;?}45X)%I#mW`sXC;~e&N1d5EemQLeywu_dpBHC$J~4jRzD3w6$IEHH=ql z4i>$lViS2UKL>SnJ$B!3%@%(?{%`~3h1{#nvm|_@v~$1ydPk?O(oN9-`ihxrvBf3U z`d|QGBB6~m|4bupu;?T`Zrr7ydd5JC#t?;uR>8nfZ1oem#HQ(k{p}}(kI^G~2?`9r z4-(@U^E-qm2+3`zrN1w!sgpHa(mWWI8u_xkyuO8UeRZ{*8xsG@G4`R=*Nxsie;(*7Pm^TXQWUE>F!EblBh>DX_weel%&4^)z7A{oNzyKwruyT^LGNyt$ zt{8IU(Yd4^j+^2uH{Sk(J?EQf1Z)kDbCSqt`$Yvo*sP206I>$r@D#dE%K-k&VJTN^ zuk!>lWg1b+g{AFvzCTsn&S#^g#97y&p

AIapx` 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 diff --git a/docs/sources/wishbone_classic_read.json b/docs/sources/wishbone_classic_read.json index ef1e966b2..39e996b1d 100644 --- a/docs/sources/wishbone_classic_read.json +++ b/docs/sources/wishbone_classic_read.json @@ -1,6 +1,5 @@ {signal: [ {name: 'clk', wave: 'p....|...'}, - {name: 'wb_tag_o', wave: 'x3...|.x.', data: ['Tag']}, {name: 'wb_adr_o', wave: 'x3...|.x.', data: ['Address']}, {name: 'wb_dat_i', wave: 'x....|3x.', data: ['rdata']}, {name: 'wb_dat_o', wave: 'x....|.x.', data: ['Wdata']}, @@ -8,7 +7,6 @@ {name: 'wb_sel_o', wave: 'x....|.x.', data: ['Byte_enable']}, {name: 'wb_stb_o', wave: '01...|.0.'}, {name: 'wb_cyc_o', wave: '01...|.0.'}, - {name: 'wb_lock_o', wave: '0....|...'}, {name: 'wb_ack_i', wave: '0....|10.'}, {name: 'wb_err_i', wave: '0....|...'}, ]} diff --git a/docs/sources/wishbone_pipelined_write.json b/docs/sources/wishbone_pipelined_write.json index 6f6344889..74adc6502 100644 --- a/docs/sources/wishbone_pipelined_write.json +++ b/docs/sources/wishbone_pipelined_write.json @@ -1,6 +1,5 @@ {signal: [ {name: 'clk', wave: 'p....|...'}, - {name: 'wb_tag_o', wave: 'x3...|.x.', data: ['Tag']}, {name: 'wb_adr_o', wave: 'x3...|.x.', data: ['Address']}, {name: 'wb_dat_i', wave: 'x....|.x.'}, {name: 'wb_dat_o', wave: 'x3...|.x.', data: ['Wdata']}, @@ -8,7 +7,6 @@ {name: 'wb_sel_o', wave: 'x3...|.x.', data: ['Byte_enable']}, {name: 'wb_stb_o', wave: '010..|...'}, {name: 'wb_cyc_o', wave: '01...|.0.'}, - {name: 'wb_lock_o', wave: '0....|...'}, {name: 'wb_ack_i', wave: '0....|10.'}, {name: 'wb_err_i', wave: '0....|...'}, ]} From 4f0346b236131ac2ee4363bbac591cdf488f50b5 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:27:18 +0100 Subject: [PATCH 2/6] [docs] remove Wishbone Tag signal --- docs/datasheet/soc.adoc | 2 -- docs/datasheet/soc_wishbone.adoc | 16 ++-------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/docs/datasheet/soc.adoc b/docs/datasheet/soc.adoc index 277797f81..444639805 100644 --- a/docs/datasheet/soc.adoc +++ b/docs/datasheet/soc.adoc @@ -71,7 +71,6 @@ bits/channels are hardwired to zero. [NOTE] Some interfaces (like the TWI and the 1-Wire bus) require tri-state drivers in the designs top module. - .NEORV32 Processor Signal List [cols="<3,^1,^1,^1,<8"] [options="header",grid="rows"] @@ -87,7 +86,6 @@ Some interfaces (like the TWI and the 1-Wire bus) require tri-state drivers in t | `jtag_tdo_o` | 1 | out | - | serial data output | `jtag_tms_i` | 1 | in | `'L'` | mode select 5+^| **<<_processor_external_memory_interface_wishbone>>** -| `wb_tag_o` | 3 | out | - | tag (access type identifier) | `wb_adr_o` | 32 | out | - | destination address | `wb_dat_i` | 32 | in | `'L'` | write data | `wb_dat_o` | 32 | out | - | read data diff --git a/docs/datasheet/soc_wishbone.adoc b/docs/datasheet/soc_wishbone.adoc index 22da1e944..07150735b 100644 --- a/docs/datasheet/soc_wishbone.adoc +++ b/docs/datasheet/soc_wishbone.adoc @@ -7,8 +7,7 @@ |======================= | Hardware source file(s): | neorv32_wishbone.vhd | | Software driver file(s): | none | _implicitly used_ -| Top entity port: | `wb_tag_o` | request tag output (3-bit) -| | `wb_adr_o` | address output (32-bit) +| Top entity port: | `wb_adr_o` | address output (32-bit) | | `wb_dat_i` | data input (32-bit) | | `wb_dat_o` | data output (32-bit) | | `wb_we_o` | write enable (1-bit) @@ -17,14 +16,12 @@ | | `wb_cyc_o` | valid cycle (1-bit) | | `wb_ack_i` | acknowledge (1-bit) | | `wb_err_i` | bus error (1-bit) -| | `fence_o` | an executed `fence` instruction -| | `fencei_o` | an executed `fence.i` instruction | Configuration generics: | `MEM_EXT_EN` | enable external memory interface when `true` | | `MEM_EXT_TIMEOUT` | number of clock cycles after which an unacknowledged external bus access will auto-terminate (0 = disabled) | | `MEM_EXT_PIPE_MODE` | when `false` (default): classic/standard Wishbone protocol; when `true`: pipelined Wishbone protocol | | `MEM_EXT_BIG_ENDIAN` | byte-order (Endianness) of external memory interface; `true`=BIG, `false`=little (default) | | `MEM_EXT_ASYNC_RX` | use registered RX path when `false` (default); use async/direct RX path when `true` -| | `MEM_EXT_ASYNC_TX_` | use registered TX path when `false` (default); use async/direct TX path when `true` +| | `MEM_EXT_ASYNC_TX` | use registered TX path when `false` (default); use async/direct TX path when `true` | CPU interrupts: | none | |======================= @@ -85,15 +82,6 @@ or terminate (via `wb_err_i`) the transfer within `MEM_EXT_TIMEOUT` clock cycles setting `wb_cyc_o` low again and a CPU load/store/instruction fetch bus access fault exception is raised. -**Wishbone Tag** - -The 3-bit wishbone `wb_tag_o` signal provides additional information regarding the access type: - -* `wb_tag_o(0)`: `1` = privileged access (CPU is in machine mode); `0` = unprivileged access (CPU is not in machine mode) -* `wb_tag_o(1)`: always zero -* `wb_tag_o(2)`: `1` = instruction fetch access, `0` = data access - - **Endianness** The NEORV32 CPU and the Processor setup are *little-endian* architectures. To allow direct connection From 933b842e7172d8d3c63dee30a06ff7797f1fd85b Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:29:27 +0100 Subject: [PATCH 3/6] [rtl] :warning: remove Wishbone tag signal --- rtl/core/neorv32_package.vhd | 3 +-- rtl/core/neorv32_wishbone.vhd | 12 ------------ .../neorv32_SystemTop_AvalonMM.vhd | 2 -- .../neorv32_SystemTop_axi4lite.vhd | 12 ++---------- .../neorv32_litex_core_complex.vhd | 1 - sim/neorv32_tb.vhd | 6 ------ sim/simple/neorv32_tb.simple.vhd | 6 ------ 7 files changed, 3 insertions(+), 39 deletions(-) diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd index 00ca301f2..b5bec914f 100644 --- a/rtl/core/neorv32_package.vhd +++ b/rtl/core/neorv32_package.vhd @@ -53,7 +53,7 @@ package neorv32_package is -- Architecture Constants ----------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090602"; -- hardware version + constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090603"; -- hardware version constant archid_c : natural := 19; -- official RISC-V architecture ID constant XLEN : natural := 32; -- native data path width @@ -843,7 +843,6 @@ package neorv32_package is jtag_tdo_o : out std_ulogic; jtag_tms_i : in std_ulogic := 'L'; -- Wishbone bus interface (available if MEM_EXT_EN = true) -- - wb_tag_o : out std_ulogic_vector(02 downto 0); wb_adr_o : out std_ulogic_vector(31 downto 0); wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); wb_dat_o : out std_ulogic_vector(31 downto 0); diff --git a/rtl/core/neorv32_wishbone.vhd b/rtl/core/neorv32_wishbone.vhd index fd8a2e69b..1a29fb2da 100644 --- a/rtl/core/neorv32_wishbone.vhd +++ b/rtl/core/neorv32_wishbone.vhd @@ -60,7 +60,6 @@ entity neorv32_wishbone is bus_req_i : in bus_req_t; -- bus request bus_rsp_o : out bus_rsp_t; -- bus response -- - wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag wb_adr_o : out std_ulogic_vector(31 downto 0); -- address wb_dat_i : in std_ulogic_vector(31 downto 0); -- read data wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data @@ -93,8 +92,6 @@ architecture neorv32_wishbone_rtl of neorv32_wishbone is ack : std_ulogic; err : std_ulogic; timeout : std_ulogic_vector(index_size_f(BUS_TIMEOUT) downto 0); - src : std_ulogic; - priv : std_ulogic; end record; signal ctrl : ctrl_t; signal stb_int : std_ulogic; @@ -147,8 +144,6 @@ begin ctrl.timeout <= (others => '0'); ctrl.ack <= '0'; ctrl.err <= '0'; - ctrl.src <= '0'; - ctrl.priv <= '0'; elsif rising_edge(clk_i) then -- defaults -- ctrl.state_ff <= ctrl.state; @@ -164,8 +159,6 @@ begin -- buffer (and gate) all outgoing signals -- ctrl.we <= bus_req_i.rw; ctrl.adr <= bus_req_i.addr; - ctrl.src <= bus_req_i.src; - ctrl.priv <= bus_req_i.priv; ctrl.wdat <= end_wdata; ctrl.sel <= end_byteen; ctrl.state <= '1'; @@ -205,11 +198,6 @@ begin bus_rsp_o.ack <= ctrl.ack when (async_rx_c = false) else ack_gated; bus_rsp_o.err <= ctrl.err when (async_rx_c = false) else err_gated; - -- wishbone interface -- - wb_tag_o(0) <= bus_req_i.priv when (ASYNC_TX = true) else ctrl.priv; -- 0 = unprivileged (U-mode), 1 = privileged (M-mode) - wb_tag_o(1) <= '0'; -- 0 = secure, 1 = non-secure - wb_tag_o(2) <= bus_req_i.src when (ASYNC_TX = true) else ctrl.src; -- 0 = data access, 1 = instruction access - stb_int <= bus_req_i.stb when (ASYNC_TX = true) else (ctrl.state and (not ctrl.state_ff)); cyc_int <= (bus_req_i.stb or ctrl.state) when (ASYNC_TX = true) else ctrl.state; diff --git a/rtl/system_integration/neorv32_SystemTop_AvalonMM.vhd b/rtl/system_integration/neorv32_SystemTop_AvalonMM.vhd index 606a9c2ce..91b88fc82 100644 --- a/rtl/system_integration/neorv32_SystemTop_AvalonMM.vhd +++ b/rtl/system_integration/neorv32_SystemTop_AvalonMM.vhd @@ -212,7 +212,6 @@ end neorv32_top_avalonmm; architecture neorv32_top_avalonmm_rtl of neorv32_top_avalonmm is -- Wishbone bus interface (available if MEM_EXT_EN = true) -- - signal wb_tag_o : std_ulogic_vector(02 downto 0); -- request tag signal wb_adr_o : std_ulogic_vector(31 downto 0); -- address signal wb_dat_i : std_ulogic_vector(31 downto 0) := (others => 'U'); -- read data signal wb_dat_o : std_ulogic_vector(31 downto 0); -- write data @@ -335,7 +334,6 @@ begin jtag_tms_i => jtag_tms_i, -- Wishbone bus interface (available if MEM_EXT_EN = true) -- - wb_tag_o => wb_tag_o, wb_adr_o => wb_adr_o, wb_dat_i => wb_dat_i, wb_dat_o => wb_dat_o, diff --git a/rtl/system_integration/neorv32_SystemTop_axi4lite.vhd b/rtl/system_integration/neorv32_SystemTop_axi4lite.vhd index 908e3eb10..537db2f3f 100644 --- a/rtl/system_integration/neorv32_SystemTop_axi4lite.vhd +++ b/rtl/system_integration/neorv32_SystemTop_axi4lite.vhd @@ -321,7 +321,6 @@ architecture neorv32_SystemTop_axi4lite_rtl of neorv32_SystemTop_axi4lite is cyc : std_ulogic; -- valid cycle ack : std_ulogic; -- transfer acknowledge err : std_ulogic; -- transfer error - tag : std_ulogic_vector(02 downto 0); -- tag end record; signal wb_core : wb_bus_t; @@ -447,7 +446,6 @@ begin jtag_tdo_o => jtag_tdo_o_int, -- serial data output jtag_tms_i => jtag_tms_i_int, -- mode select -- Wishbone bus interface (available if MEM_EXT_EN = true) -- - wb_tag_o => wb_core.tag, -- tag wb_adr_o => wb_core.adr, -- address wb_dat_i => wb_core.di, -- read data wb_dat_o => wb_core.do, -- write data @@ -618,10 +616,7 @@ begin -- AXI4-Lite Read Address Channel -- m_axi_araddr <= std_logic_vector(wb_core.adr); m_axi_arvalid <= std_logic((wb_core.cyc and (not wb_core.we)) and (not ctrl.radr_received)); ---m_axi_arprot <= "000"; -- recommended by AMD - m_axi_arprot(0) <= wb_core.tag(0); -- 0:unprivileged access, 1:privileged access - m_axi_arprot(1) <= wb_core.tag(1); -- 0:secure access, 1:non-secure access - m_axi_arprot(2) <= wb_core.tag(2); -- 0:data access, 1:instruction access + m_axi_arprot <= "000"; -- recommended by AMD -- AXI4-Lite Read Data Channel -- m_axi_rready <= std_logic(wb_core.cyc and (not wb_core.we)); @@ -632,10 +627,7 @@ begin -- AXI4-Lite Write Address Channel -- m_axi_awaddr <= std_logic_vector(wb_core.adr); m_axi_awvalid <= std_logic((wb_core.cyc and wb_core.we) and (not ctrl.wadr_received)); ---m_axi_awprot <= "000"; -- recommended by AMD - m_axi_awprot(0) <= wb_core.tag(0); -- 0:unprivileged access, 1:privileged access - m_axi_awprot(1) <= wb_core.tag(1); -- 0:secure access, 1:non-secure access - m_axi_awprot(2) <= wb_core.tag(2); -- 0:data access, 1:instruction access + m_axi_awprot <= "000"; -- recommended by AMD -- AXI4-Lite Write Data Channel -- m_axi_wdata <= std_logic_vector(wb_core.do); diff --git a/rtl/system_integration/neorv32_litex_core_complex.vhd b/rtl/system_integration/neorv32_litex_core_complex.vhd index 376484d5c..9172692c4 100644 --- a/rtl/system_integration/neorv32_litex_core_complex.vhd +++ b/rtl/system_integration/neorv32_litex_core_complex.vhd @@ -217,7 +217,6 @@ begin jtag_tdo_o => jtag_tdo_o, -- serial data output jtag_tms_i => jtag_tms_i, -- mode select -- Wishbone bus interface -- - wb_tag_o => open, -- request tag wb_adr_o => wb_adr_o, -- address wb_dat_i => wb_dat_i, -- read data wb_dat_o => wb_dat_o, -- write data diff --git a/sim/neorv32_tb.vhd b/sim/neorv32_tb.vhd index 123c643f2..a8d045f43 100644 --- a/sim/neorv32_tb.vhd +++ b/sim/neorv32_tb.vhd @@ -140,7 +140,6 @@ architecture neorv32_tb_rtl of neorv32_tb is cyc : std_ulogic; -- valid cycle ack : std_ulogic; -- transfer acknowledge err : std_ulogic; -- transfer error - tag : std_ulogic_vector(02 downto 0); -- request tag end record; signal wb_cpu, wb_mem_a, wb_mem_b, wb_mem_c, wb_irq : wishbone_t; @@ -322,7 +321,6 @@ begin jtag_tdo_o => open, -- serial data output jtag_tms_i => '0', -- mode select -- Wishbone bus interface (available if MEM_EXT_EN = true) -- - wb_tag_o => wb_cpu.tag, -- request tag wb_adr_o => wb_cpu.addr, -- address wb_dat_i => wb_cpu.rdata, -- read data wb_dat_o => wb_cpu.wdata, -- write data @@ -439,28 +437,24 @@ begin wb_mem_a.wdata <= wb_cpu.wdata; wb_mem_a.we <= wb_cpu.we; wb_mem_a.sel <= wb_cpu.sel; - wb_mem_a.tag <= wb_cpu.tag; wb_mem_a.cyc <= wb_cpu.cyc; wb_mem_b.addr <= wb_cpu.addr; wb_mem_b.wdata <= wb_cpu.wdata; wb_mem_b.we <= wb_cpu.we; wb_mem_b.sel <= wb_cpu.sel; - wb_mem_b.tag <= wb_cpu.tag; wb_mem_b.cyc <= wb_cpu.cyc; wb_mem_c.addr <= wb_cpu.addr; wb_mem_c.wdata <= wb_cpu.wdata; wb_mem_c.we <= wb_cpu.we; wb_mem_c.sel <= wb_cpu.sel; - wb_mem_c.tag <= wb_cpu.tag; wb_mem_c.cyc <= wb_cpu.cyc; wb_irq.addr <= wb_cpu.addr; wb_irq.wdata <= wb_cpu.wdata; wb_irq.we <= wb_cpu.we; wb_irq.sel <= wb_cpu.sel; - wb_irq.tag <= wb_cpu.tag; wb_irq.cyc <= wb_cpu.cyc; -- CPU read-back signals (no mux here since peripherals have "output gates") -- diff --git a/sim/simple/neorv32_tb.simple.vhd b/sim/simple/neorv32_tb.simple.vhd index a4c72c99c..6fce5188f 100644 --- a/sim/simple/neorv32_tb.simple.vhd +++ b/sim/simple/neorv32_tb.simple.vhd @@ -131,7 +131,6 @@ architecture neorv32_tb_simple_rtl of neorv32_tb_simple is cyc : std_ulogic; -- valid cycle ack : std_ulogic; -- transfer acknowledge err : std_ulogic; -- transfer error - tag : std_ulogic_vector(02 downto 0); -- request tag end record; signal wb_cpu, wb_mem_a, wb_mem_b, wb_mem_c, wb_irq : wishbone_t; @@ -270,7 +269,6 @@ begin jtag_tdo_o => open, -- serial data output jtag_tms_i => '0', -- mode select -- Wishbone bus interface (available if MEM_EXT_EN = true) -- - wb_tag_o => wb_cpu.tag, -- request tag wb_adr_o => wb_cpu.addr, -- address wb_dat_i => wb_cpu.rdata, -- read data wb_dat_o => wb_cpu.wdata, -- write data @@ -398,28 +396,24 @@ begin wb_mem_a.wdata <= wb_cpu.wdata; wb_mem_a.we <= wb_cpu.we; wb_mem_a.sel <= wb_cpu.sel; - wb_mem_a.tag <= wb_cpu.tag; wb_mem_a.cyc <= wb_cpu.cyc; wb_mem_b.addr <= wb_cpu.addr; wb_mem_b.wdata <= wb_cpu.wdata; wb_mem_b.we <= wb_cpu.we; wb_mem_b.sel <= wb_cpu.sel; - wb_mem_b.tag <= wb_cpu.tag; wb_mem_b.cyc <= wb_cpu.cyc; wb_mem_c.addr <= wb_cpu.addr; wb_mem_c.wdata <= wb_cpu.wdata; wb_mem_c.we <= wb_cpu.we; wb_mem_c.sel <= wb_cpu.sel; - wb_mem_c.tag <= wb_cpu.tag; wb_mem_c.cyc <= wb_cpu.cyc; wb_irq.addr <= wb_cpu.addr; wb_irq.wdata <= wb_cpu.wdata; wb_irq.we <= wb_cpu.we; wb_irq.sel <= wb_cpu.sel; - wb_irq.tag <= wb_cpu.tag; wb_irq.cyc <= wb_cpu.cyc; -- CPU read-back signals (no mux here since peripherals have "output gates") -- From 473327a0c5886c4c3c174a17b5692bc1d849786d Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:33:00 +0100 Subject: [PATCH 4/6] [top] minor rtl / coding style edits --- rtl/core/neorv32_top.vhd | 176 +++++++++++++++++++-------------------- 1 file changed, 88 insertions(+), 88 deletions(-) diff --git a/rtl/core/neorv32_top.vhd b/rtl/core/neorv32_top.vhd index b8ed22fbb..f4e0c8b6e 100644 --- a/rtl/core/neorv32_top.vhd +++ b/rtl/core/neorv32_top.vhd @@ -171,7 +171,6 @@ entity neorv32_top is jtag_tms_i : in std_ulogic := 'L'; -- mode select -- Wishbone bus interface (available if MEM_EXT_EN = true) -- - wb_tag_o : out std_ulogic_vector(02 downto 0); -- request tag wb_adr_o : out std_ulogic_vector(31 downto 0); -- address wb_dat_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); -- read data wb_dat_o : out std_ulogic_vector(31 downto 0); -- write data @@ -292,9 +291,10 @@ architecture neorv32_top_rtl of neorv32_top is signal clk_gen : std_ulogic_vector(07 downto 0); signal clk_gen_en, clk_gen_en_ff : std_ulogic; -- - type cg_en_t is record - wdt, uart0, uart1, spi, twi, pwm, cfs, neoled, gptmr, xip, onewire : std_ulogic; - end record; + type cg_en_enum_t is ( + CG_CFS, CG_UART0, CG_UART1, CG_SPI, CG_TWI, CG_PWM, CG_WDT, CG_NEOLED, CG_GPTMR, CG_XIP, CG_ONEWIRE + ); + type cg_en_t is array (cg_en_enum_t) of std_ulogic; signal cg_en : cg_en_t; -- CPU status -- @@ -324,22 +324,24 @@ architecture neorv32_top_rtl of neorv32_top is signal imem_rsp, dmem_rsp, xip_rsp, boot_rsp, io_rsp, xbus_rsp : bus_rsp_t; -- bus: IO devices -- - type io_devices_t is ( + type io_devices_enum_t is ( IODEV_OCD, IODEV_SYSINFO, IODEV_NEOLED, IODEV_GPIO, IODEV_WDT, IODEV_TRNG, IODEV_TWI, IODEV_SPI, IODEV_SDI, IODEV_UART1, IODEV_UART0, IODEV_MTIME, IODEV_XIRQ, IODEV_ONEWIRE, IODEV_GPTMR, IODEV_PWM, IODEV_XIP, IODEV_CRC, IODEV_DMA, IODEV_SLINK, IODEV_CFS ); - type iodev_req_t is array (io_devices_t) of bus_req_t; - type iodev_rsp_t is array (io_devices_t) of bus_rsp_t; + type iodev_req_t is array (io_devices_enum_t) of bus_req_t; + type iodev_rsp_t is array (io_devices_enum_t) of bus_rsp_t; signal iodev_req : iodev_req_t; signal iodev_rsp : iodev_rsp_t; -- IRQs -- - signal cpu_firq : std_ulogic_vector(15 downto 0); - type irq_t is record - wdt, uart0_rx, uart0_tx, uart1_rx, uart1_tx, spi, sdi, twi, cfs, neoled, xirq, gptmr, onewire, dma, trng, slink : std_ulogic; - end record; - signal firq : irq_t; + type firq_enum_t is ( + FIRQ_WDT, FIRQ_UART0_RX, FIRQ_UART0_TX, FIRQ_UART1_RX, FIRQ_UART1_TX, FIRQ_SPI, FIRQ_SDI, FIRQ_TWI, + FIRQ_CFS, FIRQ_NEOLED, FIRQ_XIRQ, FIRQ_GPTMR, FIRQ_ONEWIRE, FIRQ_DMA, FIRQ_TRNG, FIRQ_SLINK + ); + type firq_t is array (firq_enum_t) of std_ulogic; + signal firq : firq_t; + signal cpu_firq : std_ulogic_vector(15 downto 0); signal mtime_irq : std_ulogic; -- misc -- @@ -479,8 +481,9 @@ begin clk_gen(clk_div4096_c) <= clk_div(11) and (not clk_div_ff(11)); -- clk/4096 -- fresh clocks anyone? -- - clk_gen_en <= cg_en.wdt or cg_en.uart0 or cg_en.uart1 or cg_en.spi or cg_en.twi or cg_en.pwm or - cg_en.cfs or cg_en.neoled or cg_en.gptmr or cg_en.xip or cg_en.onewire; + clk_gen_en <= cg_en(CG_WDT) or cg_en(CG_UART0) or cg_en(CG_UART1) or cg_en(CG_SPI) or + cg_en(CG_TWI) or cg_en(CG_PWM) or cg_en(CG_WDT) or cg_en(CG_NEOLED) or + cg_en(CG_GPTMR) or cg_en(CG_XIP) or cg_en(CG_ONEWIRE); -- Clock Gating --------------------------------------------------------------------------- @@ -570,22 +573,22 @@ begin ); -- fast interrupt requests (FIRQs) -- - cpu_firq(00) <= firq.wdt; -- highest priority - cpu_firq(01) <= firq.cfs; - cpu_firq(02) <= firq.uart0_rx; - cpu_firq(03) <= firq.uart0_tx; - cpu_firq(04) <= firq.uart1_rx; - cpu_firq(05) <= firq.uart1_tx; - cpu_firq(06) <= firq.spi; - cpu_firq(07) <= firq.twi; - cpu_firq(08) <= firq.xirq; - cpu_firq(09) <= firq.neoled; - cpu_firq(10) <= firq.dma; - cpu_firq(11) <= firq.sdi; - cpu_firq(12) <= firq.gptmr; - cpu_firq(13) <= firq.onewire; - cpu_firq(14) <= firq.slink; - cpu_firq(15) <= firq.trng; -- lowest priority + cpu_firq(00) <= firq(FIRQ_WDT); -- highest priority + cpu_firq(01) <= firq(FIRQ_CFS); + cpu_firq(02) <= firq(FIRQ_UART0_RX); + cpu_firq(03) <= firq(FIRQ_UART0_TX); + cpu_firq(04) <= firq(FIRQ_UART1_RX); + cpu_firq(05) <= firq(FIRQ_UART1_TX); + cpu_firq(06) <= firq(FIRQ_SPI); + cpu_firq(07) <= firq(FIRQ_TWI); + cpu_firq(08) <= firq(FIRQ_XIRQ); + cpu_firq(09) <= firq(FIRQ_NEOLED); + cpu_firq(10) <= firq(FIRQ_DMA); + cpu_firq(11) <= firq(FIRQ_SDI); + cpu_firq(12) <= firq(FIRQ_GPTMR); + cpu_firq(13) <= firq(FIRQ_ONEWIRE); + cpu_firq(14) <= firq(FIRQ_SLINK); + cpu_firq(15) <= firq(FIRQ_TRNG); -- lowest priority -- CPU Instruction Cache ------------------------------------------------------------------ @@ -681,7 +684,7 @@ begin dma_req_o => dma_req, dma_rsp_i => dma_rsp, firq_i => cpu_firq, - irq_o => firq.dma + irq_o => firq(FIRQ_DMA) ); @@ -710,7 +713,7 @@ begin iodev_rsp(IODEV_DMA) <= rsp_terminate_c; main_req <= core_req; core_rsp <= main_rsp; - firq.dma <= '0'; + firq(FIRQ_DMA) <= '0'; end generate; @@ -876,14 +879,13 @@ begin XIP_CACHE_BLOCK_SIZE => XIP_CACHE_BLOCK_SIZE ) port map ( - -- global control -- clk_i => clk_i, rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_XIP), bus_rsp_o => iodev_rsp(IODEV_XIP), xip_req_i => xip_req, xip_rsp_o => xip_rsp, - clkgen_en_o => cg_en.xip, + clkgen_en_o => cg_en(CG_XIP), clkgen_i => clk_gen, spi_csn_o => xip_csn_o, spi_clk_o => xip_clk_o, @@ -896,14 +898,14 @@ begin if not XIP_EN generate iodev_rsp(IODEV_XIP) <= rsp_terminate_c; xip_rsp <= rsp_terminate_c; - cg_en.xip <= '0'; + cg_en(CG_XIP) <= '0'; xip_csn_o <= '1'; xip_clk_o <= '0'; xip_dat_o <= '0'; end generate; - -- External Wishbone Gateway (WISHBONE) --------------------------------------------------- + -- External Bus (WISHBONE) ---------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- neorv32_wishbone_inst_true: if MEM_EXT_EN generate @@ -921,7 +923,6 @@ begin bus_req_i => xbus_req, bus_rsp_o => xbus_rsp, -- - wb_tag_o => wb_tag_o, wb_adr_o => wb_adr_o, wb_dat_i => wb_dat_i, wb_dat_o => wb_dat_o, @@ -943,7 +944,6 @@ begin wb_sel_o <= (others => '0'); wb_stb_o <= '0'; wb_cyc_o <= '0'; - wb_tag_o <= (others => '0'); end generate; end generate; -- /memory_system @@ -1027,9 +1027,9 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_CFS), bus_rsp_o => iodev_rsp(IODEV_CFS), - clkgen_en_o => cg_en.cfs, + clkgen_en_o => cg_en(CG_CFS), clkgen_i => clk_gen, - irq_o => firq.cfs, + irq_o => firq(FIRQ_CFS), cfs_in_i => cfs_in_i, cfs_out_o => cfs_out_o ); @@ -1038,8 +1038,8 @@ begin neorv32_cfs_inst_false: if not IO_CFS_EN generate iodev_rsp(IODEV_CFS) <= rsp_terminate_c; - cg_en.cfs <= '0'; - firq.cfs <= '0'; + cg_en(CG_CFS) <= '0'; + firq(FIRQ_CFS) <= '0'; cfs_out_o <= (others => '0'); end generate; @@ -1061,7 +1061,7 @@ begin sdi_clk_i => sdi_clk_i, sdi_dat_i => sdi_dat_i, sdi_dat_o => sdi_dat_o, - irq_o => firq.sdi + irq_o => firq(FIRQ_SDI) ); end generate; @@ -1069,7 +1069,7 @@ begin if not IO_SDI_EN generate iodev_rsp(IODEV_SDI) <= rsp_terminate_c; sdi_dat_o <= '0'; - firq.sdi <= '0'; + firq(FIRQ_SDI) <= '0'; end generate; @@ -1111,9 +1111,9 @@ begin bus_rsp_o => iodev_rsp(IODEV_WDT), cpu_debug_i => cpu_debug, cpu_sleep_i => cpu_sleep, - clkgen_en_o => cg_en.wdt, + clkgen_en_o => cg_en(CG_WDT), clkgen_i => clk_gen, - irq_o => firq.wdt, + irq_o => firq(FIRQ_WDT), rstn_o => rstn_wdt ); end generate; @@ -1121,9 +1121,9 @@ begin neorv32_wdt_inst_false: if not IO_WDT_EN generate iodev_rsp(IODEV_WDT) <= rsp_terminate_c; - firq.wdt <= '0'; + firq(FIRQ_WDT) <= '0'; + cg_en(CG_WDT) <= '0'; rstn_wdt <= '1'; - cg_en.wdt <= '0'; end generate; @@ -1179,14 +1179,14 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_UART0), bus_rsp_o => iodev_rsp(IODEV_UART0), - clkgen_en_o => cg_en.uart0, + clkgen_en_o => cg_en(CG_UART0), clkgen_i => clk_gen, uart_txd_o => uart0_txd_o, uart_rxd_i => uart0_rxd_i, uart_rts_o => uart0_rts_o, uart_cts_i => uart0_cts_i, - irq_rx_o => firq.uart0_rx, - irq_tx_o => firq.uart0_tx + irq_rx_o => firq(FIRQ_UART0_RX), + irq_tx_o => firq(FIRQ_UART0_TX) ); end generate; @@ -1195,9 +1195,9 @@ begin iodev_rsp(IODEV_UART0) <= rsp_terminate_c; uart0_txd_o <= '0'; uart0_rts_o <= '1'; - cg_en.uart0 <= '0'; - firq.uart0_rx <= '0'; - firq.uart0_tx <= '0'; + cg_en(CG_UART0) <= '0'; + firq(FIRQ_UART0_RX) <= '0'; + firq(FIRQ_UART0_TX) <= '0'; end generate; @@ -1216,14 +1216,14 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_UART1), bus_rsp_o => iodev_rsp(IODEV_UART1), - clkgen_en_o => cg_en.uart1, + clkgen_en_o => cg_en(CG_UART1), clkgen_i => clk_gen, uart_txd_o => uart1_txd_o, uart_rxd_i => uart1_rxd_i, uart_rts_o => uart1_rts_o, uart_cts_i => uart1_cts_i, - irq_rx_o => firq.uart1_rx, - irq_tx_o => firq.uart1_tx + irq_rx_o => firq(FIRQ_UART1_RX), + irq_tx_o => firq(FIRQ_UART1_TX) ); end generate; @@ -1232,9 +1232,9 @@ begin iodev_rsp(IODEV_UART1) <= rsp_terminate_c; uart1_txd_o <= '0'; uart1_rts_o <= '1'; - cg_en.uart1 <= '0'; - firq.uart1_rx <= '0'; - firq.uart1_tx <= '0'; + cg_en(CG_UART1) <= '0'; + firq(FIRQ_UART1_RX) <= '0'; + firq(FIRQ_UART1_TX) <= '0'; end generate; @@ -1251,13 +1251,13 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_SPI), bus_rsp_o => iodev_rsp(IODEV_SPI), - clkgen_en_o => cg_en.spi, + clkgen_en_o => cg_en(CG_SPI), clkgen_i => clk_gen, spi_clk_o => spi_clk_o, spi_dat_o => spi_dat_o, spi_dat_i => spi_dat_i, spi_csn_o => spi_csn_o, - irq_o => firq.spi + irq_o => firq(FIRQ_SPI) ); end generate; @@ -1267,8 +1267,8 @@ begin spi_clk_o <= '0'; spi_dat_o <= '0'; spi_csn_o <= (others => '1'); - cg_en.spi <= '0'; - firq.spi <= '0'; + cg_en(CG_SPI) <= '0'; + firq(FIRQ_SPI) <= '0'; end generate; @@ -1282,13 +1282,13 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_TWI), bus_rsp_o => iodev_rsp(IODEV_TWI), - clkgen_en_o => cg_en.twi, + clkgen_en_o => cg_en(CG_TWI), clkgen_i => clk_gen, twi_sda_i => twi_sda_i, twi_sda_o => twi_sda_o, twi_scl_i => twi_scl_i, twi_scl_o => twi_scl_o, - irq_o => firq.twi + irq_o => firq(FIRQ_TWI) ); end generate; @@ -1297,8 +1297,8 @@ begin iodev_rsp(IODEV_TWI) <= rsp_terminate_c; twi_sda_o <= '1'; twi_scl_o <= '1'; - cg_en.twi <= '0'; - firq.twi <= '0'; + cg_en(CG_TWI) <= '0'; + firq(FIRQ_TWI) <= '0'; end generate; @@ -1315,7 +1315,7 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_PWM), bus_rsp_o => iodev_rsp(IODEV_PWM), - clkgen_en_o => cg_en.pwm, + clkgen_en_o => cg_en(CG_PWM), clkgen_i => clk_gen, pwm_o => pwm_o ); @@ -1324,7 +1324,7 @@ begin neorv32_pwm_inst_false: if not io_pwm_en_c generate iodev_rsp(IODEV_PWM) <= rsp_terminate_c; - cg_en.pwm <= '0'; + cg_en(CG_PWM) <= '0'; pwm_o <= (others => '0'); end generate; @@ -1342,14 +1342,14 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_TRNG), bus_rsp_o => iodev_rsp(IODEV_TRNG), - irq_o => firq.trng + irq_o => firq(FIRQ_TRNG) ); end generate; neorv32_trng_inst_false: if not IO_TRNG_EN generate iodev_rsp(IODEV_TRNG) <= rsp_terminate_c; - firq.trng <= '0'; + firq(FIRQ_TRNG) <= '0'; end generate; @@ -1366,9 +1366,9 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_NEOLED), bus_rsp_o => iodev_rsp(IODEV_NEOLED), - clkgen_en_o => cg_en.neoled, + clkgen_en_o => cg_en(CG_NEOLED), clkgen_i => clk_gen, - irq_o => firq.neoled, + irq_o => firq(FIRQ_NEOLED), neoled_o => neoled_o ); end generate; @@ -1376,8 +1376,8 @@ begin neorv32_neoled_inst_false: if not IO_NEOLED_EN generate iodev_rsp(IODEV_NEOLED) <= rsp_terminate_c; - cg_en.neoled <= '0'; - firq.neoled <= '0'; + cg_en(CG_NEOLED) <= '0'; + firq(FIRQ_NEOLED) <= '0'; neoled_o <= '0'; end generate; @@ -1399,14 +1399,14 @@ begin bus_req_i => iodev_req(IODEV_XIRQ), bus_rsp_o => iodev_rsp(IODEV_XIRQ), xirq_i => xirq_i, - cpu_irq_o => firq.xirq + cpu_irq_o => firq(FIRQ_XIRQ) ); end generate; neorv32_xirq_inst_false: if not io_xirq_en_c generate iodev_rsp(IODEV_XIRQ) <= rsp_terminate_c; - firq.xirq <= '0'; + firq(FIRQ_XIRQ) <= '0'; end generate; @@ -1420,9 +1420,9 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_GPTMR), bus_rsp_o => iodev_rsp(IODEV_GPTMR), - clkgen_en_o => cg_en.gptmr, + clkgen_en_o => cg_en(CG_GPTMR), clkgen_i => clk_gen, - irq_o => firq.gptmr, + irq_o => firq(FIRQ_GPTMR), capture_i => gptmr_trig_i ); end generate; @@ -1430,8 +1430,8 @@ begin neorv32_gptmr_inst_false: if not IO_GPTMR_EN generate iodev_rsp(IODEV_GPTMR) <= rsp_terminate_c; - cg_en.gptmr <= '0'; - firq.gptmr <= '0'; + cg_en(CG_GPTMR) <= '0'; + firq(FIRQ_GPTMR) <= '0'; end generate; @@ -1445,11 +1445,11 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_ONEWIRE), bus_rsp_o => iodev_rsp(IODEV_ONEWIRE), - clkgen_en_o => cg_en.onewire, + clkgen_en_o => cg_en(CG_ONEWIRE), clkgen_i => clk_gen, onewire_i => onewire_i, onewire_o => onewire_o, - irq_o => firq.onewire + irq_o => firq(FIRQ_ONEWIRE) ); end generate; @@ -1457,8 +1457,8 @@ begin if not IO_ONEWIRE_EN generate iodev_rsp(IODEV_ONEWIRE) <= rsp_terminate_c; onewire_o <= '1'; - cg_en.onewire <= '0'; - firq.onewire <= '0'; + cg_en(CG_ONEWIRE) <= '0'; + firq(FIRQ_ONEWIRE) <= '0'; end generate; @@ -1477,7 +1477,7 @@ begin rstn_i => rstn_sys, bus_req_i => iodev_req(IODEV_SLINK), bus_rsp_o => iodev_rsp(IODEV_SLINK), - irq_o => firq.slink, + irq_o => firq(FIRQ_SLINK), -- RX stream interface -- slink_rx_data_i => slink_rx_dat_i, slink_rx_valid_i => slink_rx_val_i, @@ -1494,7 +1494,7 @@ begin neorv32_slink_inst_false: if not IO_SLINK_EN generate iodev_rsp(IODEV_SLINK) <= rsp_terminate_c; - firq.slink <= '0'; + firq(FIRQ_SLINK) <= '0'; slink_rx_rdy_o <= '0'; slink_tx_dat_o <= (others => '0'); slink_tx_val_o <= '0'; From b2192976571e7dbee82e93fc9354c613a95ece01 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:43:38 +0100 Subject: [PATCH 5/6] [cache] code clean-ups and optimizations --- rtl/core/neorv32_cache.vhd | 56 ++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/rtl/core/neorv32_cache.vhd b/rtl/core/neorv32_cache.vhd index 8ac9d5ee6..ed78e7daf 100644 --- a/rtl/core/neorv32_cache.vhd +++ b/rtl/core/neorv32_cache.vhd @@ -830,18 +830,16 @@ architecture neorv32_cache_bus_rtl of neorv32_cache_bus is constant index_size_c : natural := index_size_f(NUM_BLOCKS); constant tag_size_c : natural := 32 - (offset_size_c + index_size_c + 2); - -- host request buffer -- - signal hreq : bus_req_t; - -- control fsm -- - type state_t is (S_IDLE, S_CHECK, S_DOWNLOAD_REQ, S_DOWNLOAD_RSP, S_UPLOAD_GET, S_UPLOAD_REQ, S_UPLOAD_RSP, S_FLUSH_START, S_FLUSH_READ, S_FLUSH_CHECK); + type state_t is (S_IDLE, S_CHECK, S_DOWNLOAD_REQ, S_DOWNLOAD_RSP, S_UPLOAD_GET, + S_UPLOAD_REQ, S_UPLOAD_RSP, S_FLUSH_START, S_FLUSH_READ, S_FLUSH_CHECK); signal state, upret, state_nxt, upret_nxt: state_t; -- address generator -- type addr_t is record tag : std_ulogic_vector(tag_size_c-1 downto 0); - ind : std_ulogic_vector(index_size_c-1 downto 0); - off : std_ulogic_vector(offset_size_c-1 downto 0); -- WORD offset! + idx : std_ulogic_vector(index_size_c-1 downto 0); + ofs : std_ulogic_vector(offset_size_c-1 downto 0); -- WORD offset! end record; signal haddr, baddr, addr, addr_nxt : addr_t; @@ -851,13 +849,13 @@ begin -- ------------------------------------------------------------------------------------------- -- base address of original host access -- haddr.tag <= host_req_i.addr(31 downto (32-tag_size_c)); - haddr.ind <= host_req_i.addr((offset_size_c+2+index_size_c)-1 downto offset_size_c+2); - haddr.off <= (others => '0'); -- unused + haddr.idx <= (others => '0'); -- unused + haddr.ofs <= (others => '0'); -- unused -- base address of indexed cache block -- baddr.tag <= base_i(31 downto (32-tag_size_c)); - baddr.ind <= base_i((offset_size_c+2+index_size_c)-1 downto offset_size_c+2); - baddr.off <= (others => '0'); -- unused + baddr.idx <= base_i((offset_size_c+2+index_size_c)-1 downto offset_size_c+2); + baddr.ofs <= (others => '0'); -- unused -- Control Engine FSM Sync ---------------------------------------------------------------- @@ -868,21 +866,19 @@ begin state <= S_IDLE; upret <= S_IDLE; addr.tag <= (others => '0'); - addr.ind <= (others => '0'); - addr.off <= (others => '0'); - hreq <= req_terminate_c; + addr.idx <= (others => '0'); + addr.ofs <= (others => '0'); elsif rising_edge(clk_i) then state <= state_nxt; upret <= upret_nxt; addr <= addr_nxt; - hreq <= host_req_i; end if; end process ctrl_engine_sync; -- Control Engine FSM Comb ---------------------------------------------------------------- -- ------------------------------------------------------------------------------------------- - ctrl_engine_comb: process(state, upret, addr, hreq, haddr, baddr, bus_rsp_i, cmd_sync_i, cmd_miss_i, rdata_i, dirty_i) + ctrl_engine_comb: process(state, upret, addr, haddr, baddr, bus_rsp_i, cmd_sync_i, cmd_miss_i, rdata_i, dirty_i) begin -- control engine defaults -- state_nxt <= state; @@ -890,7 +886,7 @@ begin addr_nxt <= addr; -- cache defaults -- - addr_o <= addr.tag & addr.ind & addr.off & "00"; -- always word-aligned + addr_o <= addr.tag & addr.idx & addr.ofs & "00"; -- always word-aligned we_o <= (others => '0'); swe_o <= '0'; wdata_o <= bus_rsp_i.data; @@ -902,17 +898,18 @@ begin -- bus interface defaults -- bus_req_o <= req_terminate_c; -- all-zero - bus_req_o.addr <= addr.tag & addr.ind & addr.off & "00"; -- always word-aligned + bus_req_o.addr <= addr.tag & addr.idx & addr.ofs & "00"; -- always word-aligned bus_req_o.data <= rdata_i; bus_req_o.ben <= (others => '1'); -- full-word writes only - bus_req_o.priv <= hreq.priv; -- keep original privilege level + bus_req_o.src <= '0'; -- cache accesses are always "data" accesses + bus_req_o.priv <= '0'; -- cache accesses are always "unprivileged" accesses -- fsm -- case state is when S_IDLE => -- wait for request -- ------------------------------------------------------------ - addr_nxt.off <= (others => '0'); -- align block base address for upload/download (and flush) + addr_nxt.ofs <= (others => '0'); -- align block base address for upload/download (and flush) if (cmd_sync_i = '1') then -- cache sync state_nxt <= S_FLUSH_START; elsif (cmd_miss_i = '1') then -- cache miss @@ -921,14 +918,13 @@ begin when S_CHECK => -- check if accessed block is dirty (cache address is still applied by host controller!) -- ------------------------------------------------------------ - upret_nxt <= S_DOWNLOAD_REQ; -- go straight to S_DOWNLOAD_REQ when S_UPLOAD_GET has completed (if executed) + upret_nxt <= S_DOWNLOAD_REQ; -- go straight to S_DOWNLOAD_REQ when S_UPLOAD_GET has completed (if executed) + addr_nxt.idx <= baddr.idx; -- index of reference cache block if (dirty_i = '1') then -- block is dirty, upload first addr_nxt.tag <= baddr.tag; -- base address (tag + index) of accessed block - addr_nxt.ind <= baddr.ind; state_nxt <= S_UPLOAD_GET; - else -- block is clean, download new block and override + else -- block is clean, download new block addr_nxt.tag <= haddr.tag; -- base address (tag + index) of requested block - addr_nxt.ind <= haddr.ind; state_nxt <= S_DOWNLOAD_REQ; end if; @@ -946,8 +942,8 @@ begin swe_o <= '1'; -- cache: write status bit (bus error response) new_o <= '1'; -- set new block (set tag, make valid, make clean) if (bus_rsp_i.ack = '1') or (bus_rsp_i.err = '1') then -- wait for response - addr_nxt.off <= std_ulogic_vector(unsigned(addr.off) + 1); - if (and_reduce_f(addr.off) = '1') then -- block completed? offset will be all-zero again after block completion + addr_nxt.ofs <= std_ulogic_vector(unsigned(addr.ofs) + 1); + if (and_reduce_f(addr.ofs) = '1') then -- block completed? offset will be all-zero again after block completion state_nxt <= S_IDLE; else -- get next word state_nxt <= S_DOWNLOAD_REQ; @@ -971,8 +967,8 @@ begin bus_req_o.rw <= '1'; -- write access new_o <= '1'; -- set new block (set tag, make valid, make clean) if (bus_rsp_i.ack = '1') or (bus_rsp_i.err = '1') then -- wait for response - addr_nxt.off <= std_ulogic_vector(unsigned(addr.off) + 1); - if (and_reduce_f(addr.off) = '1') then -- block completed? offset will be all-zero again after block completion + addr_nxt.ofs <= std_ulogic_vector(unsigned(addr.ofs) + 1); + if (and_reduce_f(addr.ofs) = '1') then -- block completed? offset will be all-zero again after block completion state_nxt <= upret; -- go back to "upload-done return state" else -- get next word state_nxt <= S_UPLOAD_GET; @@ -982,7 +978,7 @@ begin when S_FLUSH_START => -- start checking for dirty blocks -- ------------------------------------------------------------ - addr_nxt.ind <= (others => '0'); -- start with index 0 + addr_nxt.idx <= (others => '0'); -- start with index 0 upret_nxt <= S_FLUSH_CHECK; -- come back to S_FLUSH_CHECK after block upload state_nxt <= S_FLUSH_READ; @@ -997,8 +993,8 @@ begin if (dirty_i = '1') then -- block dirty? state_nxt <= S_UPLOAD_GET; else -- move on to next block - addr_nxt.ind <= std_ulogic_vector(unsigned(addr.ind) + 1); - if (and_reduce_f(addr.ind) = '1') then -- all blocks done? + addr_nxt.idx <= std_ulogic_vector(unsigned(addr.idx) + 1); + if (and_reduce_f(addr.idx) = '1') then -- all blocks done? bus_req_o.fence <= '1'; -- forward fence request to downstream memories state_nxt <= S_IDLE; else -- go to next block From 5a905349de667b1ec1d495aff4bdb32bfbf2a435 Mon Sep 17 00:00:00 2001 From: stnolting <22944758+stnolting@users.noreply.github.com> Date: Mon, 11 Mar 2024 18:20:44 +0100 Subject: [PATCH 6/6] [changelog] add v1.9.6.3 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9c4063f8..b0977c2bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12 | Date | Version | Comment | Link | |:----:|:-------:|:--------|:----:| +| 11.03.2024 | 1.9.6.3 | :warning: remove Wishbone tag signal; minor rtl edits and optimizations | [#845](https://github.com/stnolting/neorv32/pull/845) | | 10.03.2024 | 1.9.6.2 | minor rtl clean-ups, optimizations and fixes | [#843](https://github.com/stnolting/neorv32/pull/843) | | 09.03.2024 | 1.9.6.1 | add generic cache module (not used yet) | [#842](https://github.com/stnolting/neorv32/pull/842) | | 01.03.2024 | [**:rocket:1.9.6**](https://github.com/stnolting/neorv32/releases/tag/v1.9.6) | **New release** | |