Commit a4b95cca authored by marvin.damschen's avatar marvin.damschen Committed by Marvin Damschen
Browse files

Add benchmarks, example. Fixes.

- add command queue benchmark

- enable dsu trace buffers

- add example

- update example, add RESET_AFTER_RECONFIG property to pr_leds pblock

compress bitstream, move pblock and reset after reconfig, update example

- add benchmark with dma conflicts
parent e7afd19b
-------------------------------------------------------------------------------
-- Title : dma_controller
-- Project :
-------------------------------------------------------------------------------
-- File : dma_controller.vhd
-- Author : Martin Riedlberger <riedlberger@i80pc127>
-- Company :
-- Created : 2015-03-03
-- Last update: 2016-12-22
-- Platform :
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description: Simple DMA controller
-------------------------------------------------------------------------------
-- Copyright (c) 2015
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2015-03-03 1.0 riedlberger Created
-- 2016-11-13 1.1 damschen AHB Split support
-- 2016-12-22 1.2 damschen Split fix, Memset support
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library grlib;
use grlib.stdlib.all;
use grlib.amba.all;
use grlib.devices.all;
library techmap;
use techmap.gencomp.all;
entity dma_controller is
generic (
mst_hindex : integer := 0;
slv_hindex : integer := 0;
slv_haddr : integer := 0;
slv_hmask : integer := 16#FFF#;
hirq : integer := 0;
burst_max : integer := 256;
tech : integer := virtex7;
ahbaccsz : integer := 32);
port (
rstn : in std_ulogic;
clk : in std_ulogic;
ahbmi : in ahb_mst_in_type;
ahbmo : out ahb_mst_out_type;
ahbsi : in ahb_slv_in_type;
ahbso : out ahb_slv_out_type);
end entity dma_controller;
architecture rtl of dma_controller is
constant slv_hconfig : ahb_config_type := (
0 => ahb_device_reg (VENDOR_CONTRIB, CONTRIB_CORE2, 0, 0, hirq),
4 => ahb_iobar(slv_haddr, slv_hmask),
others => zero32);
constant mst_hconfig : ahb_config_type := (
0 => ahb_device_reg (VENDOR_CONTRIB, CONTRIB_CORE2, 0, 0, 0),
others => zero32);
constant dbits : integer := ahbaccsz;
constant abits : integer := log2(burst_max);
type dma_state_type is (IDLE_STATE, READ_STATE, READLAST_STATE, WRITE_STATE, WRITELAST_STATE);
type reg_type is record
slv_addr : std_logic_vector(7 downto 2);
slv_hwrite : std_ulogic;
slv_hrdata : std_logic_vector(31 downto 0);
src_addr, dst_addr : unsigned(31 downto 0);
len : unsigned(31 downto 0);
burst_len : integer range 0 to burst_max;
enable : std_ulogic;
state : dma_state_type;
cnt : integer range 0 to burst_max;
dsbl_irq : std_ulogic;
srcasval : std_ulogic;
grant : std_ulogic;
active : std_ulogic;
mexc : std_ulogic;
num_splits : unsigned(31 downto 0);
b_raddr : std_logic_vector(abits-1 downto 0);
end record reg_type;
signal r, rin : reg_type;
signal b_raddr, b_waddr : std_logic_vector(abits-1 downto 0);
signal b_datain, b_dataout : std_logic_vector(dbits-1 downto 0);
signal b_renable, b_write : std_ulogic;
begin -- architecture rtl
b_ram : syncram_2p generic map (tech => tech, abits => abits, dbits => dbits)
port map (clk, b_renable, b_raddr, b_dataout,
clk, b_write, b_waddr, b_datain);
comb : process (ahbsi, r, ahbmi, rstn, b_dataout) is
variable v : reg_type;
variable slv_haddr : std_logic_vector(7 downto 2);
variable slv_hsel : std_ulogic;
variable haddr : unsigned(31 downto 0);
variable hbusreq : std_ulogic;
variable htrans : std_logic_vector(1 downto 0);
variable hwrite : std_ulogic;
variable hsize : std_logic_vector(2 downto 0);
variable hburst : std_logic_vector(2 downto 0);
variable hwdata : std_logic_vector(dbits-1 downto 0);
variable vb_raddr, vb_waddr : std_logic_vector(abits-1 downto 0);
variable vb_renable, vb_write : std_ulogic;
variable vb_datain : std_logic_vector(dbits-1 downto 0);
variable usr_rst : std_ulogic;
variable hready : std_ulogic;
variable split : std_ulogic;
variable irq : std_logic_vector(NAHBIRQ-1 downto 0);
begin -- process comb
v := r;
slv_hsel := '0';
slv_haddr := (others => '0');
v.slv_hrdata := (others => '0');
hbusreq := r.enable;
haddr := (others => '0');
hwrite := '0';
hwdata := (others => '0');
htrans := HTRANS_IDLE;
hsize := HSIZE_WORD;
hburst := HBURST_SINGLE;
vb_raddr := (others => '0');
vb_waddr := (others => '0');
vb_datain := (others => '0');
vb_renable := '0';
vb_write := '0';
usr_rst := '0';
hready := '0';
split := '0';
irq := (others => '0');
--dma state machine
if ahbmi.hready = '1' then
v.grant := ahbmi.hgrant(mst_hindex);
if r.active = '1' and ahbmi.hresp = HRESP_ERROR then
v.mexc := '1';
v.enable := '0';
v.active := '0';
irq(hirq) := not r.dsbl_irq;
v.state := IDLE_STATE;
elsif r.active = '1' and ahbmi.hresp = HRESP_SPLIT then
v.active := '0';
split := '1';
v.num_splits := r.num_splits + 1;
else
hready := '1';
end if;
end if;
case r.state is
when IDLE_STATE =>
if r.enable = '1' then
if r.len > 0 then
if r.srcasval = '1' then
v.state := WRITE_STATE;
else
v.state := READ_STATE;
end if;
else
hbusreq := '0';
v.enable := '0';
irq(hirq) := not r.dsbl_irq;
end if;
end if;
when READ_STATE =>
if (hready = '1') and (r.cnt > 0) and (r.active = '1') then
vb_waddr := std_logic_vector(to_unsigned(r.cnt-1, abits));
vb_datain := ahbreadword(ahbmi.hrdata);
vb_write := '1';
end if;
if (hready and r.grant) = '1' then
v.active := '1';
v.cnt := r.cnt + 1;
v.src_addr := r.src_addr + 4;
if (r.cnt = r.burst_len-1) or (r.cnt = r.len-1) then
v.state := READLAST_STATE;
end if;
end if;
haddr := r.src_addr;
hburst := HBURST_INCR;
if split = '1' then
htrans := HTRANS_IDLE;
v.cnt := r.cnt - 1;
v.src_addr := r.src_addr - 4;
elsif (r.cnt = 0) or (r.src_addr(9 downto 0) = "0000000000") then
htrans := HTRANS_NONSEQ;
else
htrans := HTRANS_SEQ;
end if;
when READLAST_STATE =>
if (hready = '1') and (r.cnt > 0) and (r.active = '1') then
vb_waddr := std_logic_vector(to_unsigned(r.cnt-1, abits));
vb_datain := ahbreadword(ahbmi.hrdata);
vb_write := '1';
v.cnt := 0;
v.state := WRITE_STATE;
vb_raddr := std_logic_vector(to_unsigned(0, abits));
v.b_raddr := std_logic_vector(to_unsigned(0, abits));
vb_renable := '1';
elsif split = '1' then
v.cnt := r.cnt - 1;
v.src_addr := r.src_addr - 4;
v.state := READ_STATE;
end if;
when WRITE_STATE =>
if (hready and r.grant) = '1' then
v.active := '1';
v.cnt := r.cnt + 1;
v.dst_addr := r.dst_addr + 4;
v.len := r.len - 1;
if r.cnt = r.burst_len - 1 or r.len = 1 then
v.state := WRITELAST_STATE;
end if;
end if;
if hready = '1' then
v.b_raddr := std_logic_vector(to_unsigned(r.cnt, abits));
vb_raddr := std_logic_vector(to_unsigned(r.cnt, abits));
else
vb_raddr := r.b_raddr;
end if;
vb_renable := '1';
haddr := r.dst_addr;
if r.srcasval = '0' then
hwdata := b_dataout;
else
hwdata := std_logic_vector(r.src_addr);
end if;
hburst := HBURST_INCR;
hwrite := '1';
if split = '1' then
htrans := HTRANS_IDLE;
v.cnt := r.cnt - 1;
v.dst_addr := r.dst_addr - 4;
v.len := r.len + 1;
elsif (r.cnt = 0) or (r.dst_addr(9 downto 0) = "0000000000") then
htrans := HTRANS_NONSEQ;
else
htrans := HTRANS_SEQ;
end if;
when WRITELAST_STATE =>
vb_raddr := std_logic_vector(to_unsigned(r.cnt, abits));
vb_renable := '1';
if r.srcasval = '0' then
hwdata := b_dataout;
else
hwdata := std_logic_vector(r.src_addr);
end if;
if (hready = '1') and (not split = '1') then
v.cnt := 0;
if r.len = 0 or r.enable = '0' then
v.state := IDLE_STATE;
hbusreq := '0';
v.enable := '0';
v.active := '0';
irq(hirq) := not r.dsbl_irq;
else
if r.srcasval = '1' then
v.state := WRITE_STATE;
else
v.state := READ_STATE;
end if;
end if;
elsif split = '1' then
v.cnt := r.cnt - 1;
v.dst_addr := r.dst_addr - 4;
v.len := r.len + 1;
v.state := WRITE_STATE;
end if;
when others => null;
end case;
-- AHB-Slave
if ahbsi.hready = '1' then
slv_hsel := ahbsi.hsel(slv_hindex) and ahbsi.htrans(1);
v.slv_hwrite := ahbsi.hwrite and slv_hsel;
v.slv_addr := ahbsi.haddr(7 downto 2);
end if;
if r.slv_hwrite = '1' then
slv_haddr := r.slv_addr;
else
slv_haddr := ahbsi.haddr(7 downto 2);
end if;
--ahb slv read
if slv_hsel = '1' then
case slv_haddr is
when "000000" => v.slv_hrdata := std_logic_vector(r.src_addr);
when "000001" => v.slv_hrdata := std_logic_vector(r.dst_addr);
when "000010" => v.slv_hrdata := std_logic_vector(r.len);
when "000011" => v.slv_hrdata(0) := r.enable;
v.slv_hrdata(2) := r.mexc;
v.slv_hrdata(3) := r.dsbl_irq;
v.slv_hrdata(4) := r.srcasval;
v.slv_hrdata(31 downto 16) := std_logic_vector(to_unsigned(r.burst_len, 16));
when "000100" => v.slv_hrdata := std_logic_vector(r.num_splits);
when others => null;
end case;
end if;
--ahb slv write
if r.slv_hwrite = '1' then
case slv_haddr is
when "000000" => v.src_addr := unsigned(ahbsi.hwdata(31 downto 0));
when "000001" => v.dst_addr := unsigned(ahbsi.hwdata(31 downto 0));
when "000010" => v.len := unsigned(ahbsi.hwdata(31 downto 0));
when "000011" => v.enable := ahbsi.hwdata(0);
if v.enable = '1' then
v.num_splits := (others => '0');
v.mexc := '0';
end if;
usr_rst := ahbsi.hwdata(1);
v.dsbl_irq := ahbsi.hwdata(3);
v.srcasval := ahbsi.hwdata(4);
v.burst_len := to_integer(unsigned(ahbsi.hwdata(31 downto 16)));
when "000100" => null; -- 'num_splits' not writeable
when others => null;
end case;
end if;
--reset
if rstn = '0' or usr_rst = '1' then
v.state := IDLE_STATE;
v.src_addr := (others => '0');
v.dst_addr := (others => '0');
v.len := (others => '0');
v.enable := '0';
v.active := '0';
v.mexc := '0';
v.num_splits := (others => '0');
v.cnt := 0;
v.dsbl_irq := '0';
v.srcasval := '0';
v.burst_len := 4;
v.grant := '0';
end if;
rin <= v;
--outputs ahb slv
ahbso.hready <= '1';
ahbso.hresp <= "00";
ahbso.hrdata <= ahbdrivedata(r.slv_hrdata);
ahbso.hsplit <= (others => '0');
ahbso.hirq <= irq;
ahbso.hconfig <= slv_hconfig;
ahbso.hindex <= slv_hindex;
--outputs ahb mst
ahbmo.hbusreq <= hbusreq;
ahbmo.hlock <= '0';
ahbmo.htrans <= htrans;
ahbmo.haddr <= std_logic_vector(haddr);
ahbmo.hwrite <= hwrite;
ahbmo.hsize <= hsize;
ahbmo.hburst <= hburst;
ahbmo.hprot <= (others => '0');
ahbmo.hwdata <= ahbdrivedata(hwdata);
ahbmo.hirq <= (others => '0');
ahbmo.hconfig <= mst_hconfig;
ahbmo.hindex <= mst_hindex;
--outputs buffer
b_raddr <= vb_raddr;
b_waddr <= vb_waddr;
b_renable <= vb_renable;
b_write <= vb_write;
b_datain <= vb_datain;
end process comb;
reg : process (clk)
begin
if rising_edge(clk) then
r <= rin;
end if;
end process;
end architecture rtl;
-------------------------------------------------------------------------------
-- Title : libmisc
-- Project :
-------------------------------------------------------------------------------
-- File : libmisc.vhd
-- Author : Martin Riedlberger
-- Company :
-- Created : 2015-02-12
-- Last update: 2015-07-22
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Package containing misc component declaration
-------------------------------------------------------------------------------
-- Copyright (c) 2015
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2015-02-12 1.0 riedlberger Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library grlib;
use grlib.amba.all;
library techmap;
use techmap.gencomp.all;
library gaisler;
use gaisler.misc.all;
package libmisc is
component dma_controller is
generic (
mst_hindex : integer := 0;
slv_hindex : integer := 0;
slv_haddr : integer := 0;
slv_hmask : integer := 16#FFF#;
hirq : integer := 0;
burst_max : integer := 256;
tech : integer := virtex5);
port (
rstn : in std_ulogic;
clk : in std_ulogic;
ahbmi : in ahb_mst_in_type;
ahbmo : out ahb_mst_out_type;
ahbsi : in ahb_slv_in_type;
ahbso : out ahb_slv_out_type);
end component;
end libmisc;
#!/bin/bash
source /home/adm/xilinx_2014.4_64bit.setup # TODO adjust path to vivado 2014.4 environment
gaisler_bcc_gcc="/Software/tools/icore-compiler/sparc-elf-4.4.2_mod/bin/sparc-elf-gcc"
# Customize IP Cores in top
printf "$(date +%T) - customizing ip cores..."
......@@ -111,4 +112,13 @@ else
exit
fi
cd ..
printf "$(date +%T) - compiling software..."
cd software
$($gaisler_bcc_gcc -msoft-float benchmarks.c cmdqueue.c -o benchmarks && $gaisler_bcc_gcc -msoft-float cmdqueue.c example.c -o example)
if [ $? -eq 0 ]; then
printf "DONE\n"
else
printf "FAILED\n"
exit
fi
......@@ -70,8 +70,8 @@ package config is
constant CFG_TLB_REP : integer := 0;
constant CFG_MMU_PAGE : integer := 0;
constant CFG_DSU : integer := 1;
constant CFG_ITBSZ : integer := 0 + 64*0;
constant CFG_ATBSZ : integer := 0;
constant CFG_ITBSZ : integer := 4 + 64*0;
constant CFG_ATBSZ : integer := 4;
constant CFG_AHBPF : integer := 0;
constant CFG_LEON3FT_EN : integer := 0;
constant CFG_IUFT_EN : integer := 0;
......@@ -147,7 +147,7 @@ package config is
constant CFG_ROMMASK : integer := 16#E00# + 16#000#;
-- AHB RAM
constant CFG_AHBRAMEN : integer := 0;
constant CFG_AHBRSZ : integer := 4;
constant CFG_AHBRSZ : integer := 1;
constant CFG_AHBRADDR : integer := 16#A00#;
constant CFG_AHBRPIPE : integer := 0;
-- Gaisler Ethernet core
......@@ -310,4 +310,8 @@ package config is
--Cmdqueue & Bitstream Loader
constant CFG_CMDQUEUE_ENABLE : integer := 1;
constant CFG_CMDQUEUE_BITSTORE_ADDR : integer := 16#A10#;
--DMA Controller
constant CFG_DMA_ENABLE : integer := 1;
constant CFG_DMA_ADDR : integer := 16#A00#;
end;
......@@ -55,6 +55,7 @@ use esa.memoryctrl.all;
use work.config.all;
library ces;
use ces.libmisc.all;
use ces.cmdqueuelib.all;
entity leon3mp is
......@@ -1122,7 +1123,7 @@ begin
end generate;
-----------------------------------------------------------------------
--- Cmdqueue Reconfiguratioin Controller & LEDs ---------------------
--- CES: Cmdqueue Reconfiguratioin Controller & LEDs ----------------
-----------------------------------------------------------------------
bitloadgen: if CFG_CMDQUEUE_ENABLE = 1 generate
cmdqueue : CmdQueue_TOP
......@@ -1150,6 +1151,21 @@ begin
end generate;
leds_ctrl_inst: leds_ctrl port map ( rstn => rstn, clk => clkm, ledso => leds);
-----------------------------------------------------------------------
--- CES: DMA ---------------------------------------------------------
-----------------------------------------------------------------------
dma : if CFG_DMA_ENABLE = 1 generate
dma0 : dma_controller
generic map (mst_hindex => CFG_NCPU+CFG_AHB_UART+CFG_AHB_JTAG+CFG_GRETH+CFG_GRUSBDC+CFG_GRUSBHC*2+CFG_GRUSB_DCL+CFG_CMDQUEUE_ENABLE,
slv_hindex => 12,
slv_haddr => CFG_DMA_ADDR,
hirq => 9,
tech => memtech)
port map (rstn, clkm, ahbmi,
ahbmo(CFG_NCPU+CFG_AHB_UART+CFG_AHB_JTAG+CFG_GRETH+CFG_GRUSBDC+CFG_GRUSBHC*2+CFG_GRUSB_DCL+CFG_CMDQUEUE_ENABLE),
ahbsi, ahbso(12));
end generate;
-----------------------------------------------------------------------
--- DYNAMIC PARTIAL RECONFIGURATION ---------------------------------
......@@ -1181,7 +1197,7 @@ begin
--- Drive unused bus elements ---------------------------------------
-----------------------------------------------------------------------
nam1 : for i in (CFG_NCPU+CFG_AHB_UART+CFG_AHB_JTAG+CFG_GRETH+CFG_GRUSBDC+CFG_GRUSBHC*2+CFG_GRUSB_DCL+CFG_PRC+CFG_CMDQUEUE_ENABLE) to NAHBMST-1 generate
nam1 : for i in (CFG_NCPU+CFG_AHB_UART+CFG_AHB_JTAG+CFG_GRETH+CFG_GRUSBDC+CFG_GRUSBHC*2+CFG_GRUSB_DCL+CFG_PRC+CFG_CMDQUEUE_ENABLE+CFG_DMA_ENABLE) to NAHBMST-1 generate
ahbmo(i) <= ahbm_none;
end generate;
......
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
create_pblock pr_leds
add_cells_to_pblock [get_pblocks pr_leds] [get_cells -quiet [list {leds_ctrl_inst}]]
resize_pblock [get_pblocks pr_leds] -add {SLICE_X136Y200:SLICE_X141Y249 DSP48_X12Y80:DSP48_X12Y99}
resize_pblock [get_pblocks pr_leds] -add {SLICE_X44Y100:SLICE_X47Y149}
set_property RESET_AFTER_RECONFIG true [get_pblocks pr_leds]
set_property EXCLUDE_PLACEMENT 1 [get_pblocks pr_leds]
......@@ -270,6 +270,8 @@ read_vhdl -library testgrouppolito ${lib}/testgrouppolito/pr/dprc.vhd
read_vhdl -library testgrouppolito ${lib}/testgrouppolito/pr/sync_dprc.vhd
read_vhdl -library testgrouppolito ${lib}/testgrouppolito/pr/async_dprc.vhd
read_vhdl -library testgrouppolito ${lib}/testgrouppolito/pr/d2prc.vhd
read_vhdl -library ces ${ceslib}/misc/libmisc.vhd
read_vhdl -library ces ${ceslib}/misc/dma_controller.vhd
read_vhdl -library ces ${ceslib}/command_queue/CmdQueueLib.vhd
read_vhdl -library ces ${ceslib}/command_queue/large_syncram_dp.vhd
read_vhdl -library ces ${ceslib}/command_queue/CmdQueue.vhd
......
#include <stdio.h>
#include <string.h>
#include "defines.h"
#include "cmdqueue.h"
#include "../pr_flow/bitstreams/config0_pr_leds_partial.h"
volatile static unsigned int* cmdqueue = (unsigned int*) CMDQUEUE;
//struct for accessing the dma control register
typedef union {
struct {
union {
unsigned int *src_addr;
unsigned int val;
};
unsigned int *dst_addr;
unsigned int len;
unsigned int burst_len :16;
unsigned int :11;
unsigned int srcasval :1;
unsigned int dsbl_irq :1;
unsigned int mexc :1;
unsigned int reset :1;
unsigned int enable :1;
unsigned int num_splits;
};
struct {
union {
unsigned int *src_addr;