Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intel Arria 10 compatibility #234

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions openasip/CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ Notable changes and features
Now it's possible to optionally give a list of pairs of
<address-space-name>,<data-start>.
- Added the same option to generatebits with the same syntax.
- AlmaIF: add RAM models which infer the BRAM on Intel Arria 10
- Enabled with bram-vendor:intel in generateprocessor parameters.

Notable bugfixes
----------------------------
- ProDe: Fix operand usage and resource boxes to use default colors propagated
from system theme instead of manually setting them to black and white.
- AlmaIF: Fix a bug in almaif_decoder memory mask computation
- Add a latency to clock/lock cycle counter to increase clock frequency

2.0 November 2022
=====================
Expand Down
14 changes: 12 additions & 2 deletions openasip/data/ProGe/ifetch.vhdl.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ architecture rtl_andor of ENTITY_STR_ifetch is
signal increased_pc : std_logic_vector(IMEMADDRWIDTH-1 downto 0);
signal return_addr_reg : std_logic_vector(IMEMADDRWIDTH-1 downto 0);

signal lockcnt_increment_r, cyclecnt_increment_r : integer range 0 to 1;

-- internal signals for initializing and locking execution
signal lock : std_logic;
signal mem_en_lock_r : std_logic;
Expand Down Expand Up @@ -223,16 +225,24 @@ begin
if not sync_reset_g and rstx = '0' then -- async reset (active low)
lockcnt_r <= (others => '0');
cyclecnt_r <= (others => '0');
lockcnt_increment_r <= 0;
cyclecnt_increment_r <= 0;
elsif rising_edge(clk) then
if (sync_reset_g and rstx = '0') or db_rstx = '0' then
lockcnt_r <= (others => '0');
cyclecnt_r <= (others => '0');
lockcnt_increment_r <= 0;
cyclecnt_increment_r <= 0;
elsif db_lockreq = '0' then
if lock = '1' then
lockcnt_r <= lockcnt_r + 1;
lockcnt_increment_r <= 1;
cyclecnt_increment_r <= 0;
else
cyclecnt_r <= cyclecnt_r + 1;
lockcnt_increment_r <= 0;
cyclecnt_increment_r <= 1;
end if;
lockcnt_r <= lockcnt_r + lockcnt_increment_r;
cyclecnt_r <= cyclecnt_r + cyclecnt_increment_r;
end if;
end if;
end process;
Expand Down
2 changes: 2 additions & 0 deletions openasip/data/ProGe/platform/almaif_decoder.vhdl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ entity almaif_decoder is
m_axi_wready : in std_logic;
m_axi_wdata : out std_logic_vector(mem_dataw_g-1 downto 0);
m_axi_wstrb : out std_logic_vector(mem_dataw_g/8-1 downto 0);
m_axi_wlast : out std_logic;
--
m_axi_bvalid : in std_logic;
m_axi_bready : out std_logic;
Expand Down Expand Up @@ -270,6 +271,7 @@ begin
m_axi_wvalid <= m_axi_wvalid_r;
m_axi_wdata <= m_axi_wdata_r;
m_axi_wstrb <= m_axi_wstrb_r;
m_axi_wlast <= '1';
-- Ignore the response
m_axi_bready <= '1';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ m_axi_wvalid : out std_logic;
m_axi_wready : in std_logic;
m_axi_wdata : out std_logic_vector(pmem_data_width_g-1 downto 0);
m_axi_wstrb : out std_logic_vector(pmem_data_width_g/8-1 downto 0);
m_axi_wlast : out std_logic;
--
m_axi_bvalid : in std_logic;
m_axi_bready : out std_logic;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ signal m_axi_wvalid : std_logic;
signal m_axi_wready : std_logic;
signal m_axi_wdata : std_logic_vector(dmem_data_width_g-1 downto 0);
signal m_axi_wstrb : std_logic_vector(dmem_data_width_g/8-1 downto 0);
signal m_axi_wlast : std_logic;
--
signal m_axi_bvalid : std_logic;
signal m_axi_bready : std_logic;
Expand Down
273 changes: 273 additions & 0 deletions openasip/data/ProGe/platform/intel_dp_blockram.vhdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
-- Copyright (c) 2017-2023 Tampere University
--
-- Permission is hereby granted, free of charge, to any person obtaining a
-- copy of this software and associated documentation files (the "Software"),
-- to deal in the Software without restriction, including without limitation
-- the rights to use, copy, modify, merge, publish, distribute, sublicense,
-- and/or sell copies of the Software, and to permit persons to whom the
-- Software is furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-- DEALINGS IN THE SOFTWARE.
-------------------------------------------------------------------------------
-- Title : Intel dual-port BRAM model with handshaking
-- Project :
-------------------------------------------------------------------------------
-- File : intel_dp_blockram.vhdl
-- Author : Aleksi Tervo
-- Company : Tampere University
-- Created : 2017-06-01
-- Last update: 2023-06-08
-- Platform :
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Parametric-width byte strobe memory with handshaking
-- which infers BRAM on (at least) Intel Arria 10 FPGAs
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2017-06-01 1.0 tervoa Created (xilinx_dp_blockram.vhdl)
-- 2023-06-08 1.1 leppanet Modified the xilinx_db_bram to support Intel
-- Arria 10 FGPA
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.numeric_std.all;

entity intel_dp_blockram is generic (
addrw_g : integer := 10;
dataw_g : integer := 32;
addrw_b_g : integer := 10;
dataw_b_g : integer := 32);
port (
clk : in std_logic;
rstx : in std_logic;
-- PORT A -------------------------------------------------------
-- Access channel
a_avalid_in : in std_logic;
a_aready_out : out std_logic;
a_aaddr_in : in std_logic_vector(addrw_g-1 downto 0);
a_awren_in : in std_logic;
a_astrb_in : in std_logic_vector((dataw_g+7)/8-1 downto 0);
a_adata_in : in std_logic_vector(dataw_g-1 downto 0);
-- Read channel
a_rvalid_out : out std_logic;
a_rready_in : in std_logic;
a_rdata_out : out std_logic_vector(dataw_g-1 downto 0);
-- PORT B -------------------------------------------------------
-- Access channel
b_avalid_in : in std_logic;
b_aready_out : out std_logic;
b_aaddr_in : in std_logic_vector(addrw_b_g-1 downto 0);
b_awren_in : in std_logic;
b_astrb_in : in std_logic_vector((dataw_b_g+7)/8-1 downto 0);
b_adata_in : in std_logic_vector(dataw_b_g-1 downto 0);
-- Read channel
b_rvalid_out : out std_logic;
b_rready_in : in std_logic;
b_rdata_out : out std_logic_vector(dataw_b_g-1 downto 0)
);
end intel_dp_blockram;

architecture rtl of intel_dp_blockram is
constant b_astrb_width_c : integer := dataw_b_g/8;
constant a_dataw_padded_c : integer := (dataw_g+dataw_b_g-1)/dataw_b_g*dataw_b_g;
constant a_astrb_width_c : integer := a_dataw_padded_c/8;
constant a_padding_c : std_logic_vector(a_dataw_padded_c-dataw_g-1 downto 0)
:= (others => '0');
constant b_addr_padding_c : integer := addrw_b_g-addrw_g;
constant need_select_c : boolean := b_addr_padding_c > 0;

constant a_astrb_padding_c : std_logic_vector(a_astrb_width_c-a_astrb_in'high-2
downto 0) := (others => '0');
constant a_word_count_c : integer := a_dataw_padded_c/dataw_b_g;

signal a_addr : unsigned(addrw_g-1 downto 0);
signal b_addr : unsigned(addrw_g-1 downto 0);
signal b_select, b_select_r : unsigned(b_addr_padding_c-1 downto 0);
signal a_wdata, a_adata, a_rdata_r, a_ram_rdata_r : std_logic_vector(a_dataw_padded_c-1 downto 0);
signal b_wdata, b_adata, b_ram_rdata_r : std_logic_vector(a_dataw_padded_c-1 downto 0);
signal b_rdata_sel, b_rdata_r : std_logic_vector(dataw_b_g-1 downto 0);
signal a_enable, b_enable : std_logic;
signal a_aready_r, b_aready_r : std_logic;
signal a_live_read, b_live_read : std_logic;
signal a_live_read_r, b_live_read_r : std_logic;
signal a_rdata_valid_r, b_rdata_valid_r : std_logic;
signal a_rvalid, b_rvalid : std_logic;
signal a_astrb, b_astrb : std_logic_vector(a_astrb_width_c-1 downto 0);

type ram_type is array (2**addrw_g-1 downto 0) of std_logic_vector
(a_dataw_padded_c-1 downto 0);
shared variable RAM_ARR : ram_type;

attribute ramstyle : string;
attribute ramstyle of RAM_ARR : variable is "no_rw_check";

begin

control_comb_a : process(a_aaddr_in, a_avalid_in, a_aready_r,
a_awren_in, a_live_read_r, a_rdata_valid_r)
begin
if a_avalid_in = '1' and a_aready_r = '1' then
a_enable <= '1';
a_live_read <= not a_awren_in;
else
a_enable <= '0';
a_live_read <= '0';
end if;

a_addr <= unsigned(a_aaddr_in);
a_rvalid <= a_live_read_r or a_rdata_valid_r;
end process;

control_comb_b : process(b_aaddr_in, b_avalid_in, b_aready_r,
b_awren_in, b_live_read_r, b_rdata_valid_r,
b_astrb_in, b_select, b_adata_in)
begin
if b_avalid_in = '1' and b_aready_r = '1' then
b_enable <= '1';
b_live_read <= not b_awren_in;
else
b_enable <= '0';
b_live_read <= '0';
end if;

b_addr <= unsigned(b_aaddr_in(b_aaddr_in'high downto b_addr_padding_c));
b_select <= unsigned(b_aaddr_in(b_addr_padding_c-1 downto 0));
b_astrb <= (others => '0');

if need_select_c then
b_astrb((to_integer(b_select)+1)*b_astrb_width_c-1 downto to_integer(b_select)*b_astrb_width_c) <= b_astrb_in;
else
b_astrb(b_astrb_width_c-1 downto 0) <= b_astrb_in;
end if;

for i in 0 to a_word_count_c - 1 loop
b_wdata((i+1)*dataw_b_g-1 downto i*dataw_b_g) <= b_adata_in;
end loop;
b_rvalid <= b_live_read_r or b_rdata_valid_r;
end process;


control_sync_a : process(clk, rstx)
begin
if rstx = '0' then
a_live_read_r <= '0';
a_aready_r <= '0';
a_rdata_valid_r <= '0';
a_rdata_r <= (others => '0');
elsif rising_edge(clk) then
if a_rvalid = '1' and a_rready_in = '1' then
a_rdata_valid_r <= '0';
end if;

if a_rvalid = '1' and a_rready_in = '0' then
a_aready_r <= '0';
else
a_aready_r <= '1';
end if;

a_live_read_r <= a_live_read or a_live_read_r;
if a_live_read_r = '1' and (a_rready_in = '1' or a_rdata_valid_r = '0') then
a_live_read_r <= a_live_read;
if a_rready_in = '0' or a_rdata_valid_r = '1' then
a_rdata_valid_r <= '1';
a_rdata_r <= a_ram_rdata_r;
end if;
end if;
end if;
end process;

control_sync_b : process(clk, rstx)
begin
if rstx = '0' then
b_live_read_r <= '0';
b_aready_r <= '0';
b_rdata_valid_r <= '0';
b_rdata_r <= (others => '0');
b_select_r <= (others => '0');
elsif rising_edge(clk) then

if b_live_read = '1' then
b_select_r <= b_select;
end if;

if b_rvalid = '1' and b_rready_in = '1' then
b_rdata_valid_r <= '0';
end if;

if b_rvalid = '1' and b_rready_in = '0' then
b_aready_r <= '0';
else
b_aready_r <= '1';
end if;

b_live_read_r <= b_live_read or b_live_read_r;
if b_live_read_r = '1' and (b_rready_in = '1' or b_rdata_valid_r = '0') then
b_live_read_r <= b_live_read;
if b_rready_in = '0' or b_rdata_valid_r = '1' then
b_rdata_valid_r <= '1';
b_rdata_r <= b_rdata_sel;
end if;
end if;
end if;
end process;

a_wdata <= a_padding_c & a_adata_in;
a_astrb <= a_astrb_padding_c & a_astrb_in;

RAM_A : process(clk)
begin
if rising_edge(clk) then
if a_awren_in = '1' and a_enable = '1' then
for b in 0 to a_astrb_width_c-1 loop
if a_astrb(b) = '1' then
RAM_ARR(to_integer(a_addr))((b+1)*8-1 downto b*8)
:= a_wdata((b+1)*8-1 downto b*8);
end if;
end loop;
end if;
a_ram_rdata_r <= RAM_ARR(to_integer(a_addr));
end if;
end process;

RAM_B : process(clk)
begin
if rising_edge(clk) then
if b_awren_in = '1' and b_enable = '1' then
for i in 0 to a_astrb_width_c-1 loop
if b_astrb(i) = '1' then
RAM_ARR(to_integer(b_addr))((i+1)*8-1 downto i*8)
:= b_wdata((i+1)*8-1 downto i*8);
end if;
end loop;
end if;
b_ram_rdata_r <= RAM_ARR(to_integer(b_addr));
end if;
end process;

pad: if need_select_c generate
b_rdata_sel <= b_ram_rdata_r((to_integer(b_select_r)+1)*dataw_b_g-1
downto to_integer(b_select_r)*dataw_b_g);
end generate;
no_pad: if not need_select_c generate
b_rdata_sel <= b_ram_rdata_r(dataw_b_g-1 downto 0);
end generate;
a_rdata_out <= a_ram_rdata_r(a_rdata_out'range) when a_rdata_valid_r = '0'
else a_rdata_r(a_rdata_out'range);
b_rdata_out <= b_rdata_sel when b_rdata_valid_r = '0' else b_rdata_r;
a_aready_out <= a_aready_r;
a_rvalid_out <= a_rvalid;
b_aready_out <= b_aready_r;
b_rvalid_out <= b_rvalid;

end architecture rtl;
Loading