M6: Hinzufügen Praktikumsunterlagen

This commit is contained in:
Matthias Biermann
2024-12-09 14:48:49 +01:00
parent 25d5d0fd17
commit 0b3bea8b52
17 changed files with 1958 additions and 0 deletions
@@ -0,0 +1 @@
Die hier zur Verfügung gestellten Code-Fragmente sind nicht eigenständig lauffähig, sondern müssen in einer VHDL-Architecture abgelegt und anschließend ergänzt werden.
@@ -0,0 +1,76 @@
-----------------------
-- AXI-Lite Interface
-----------------------
S_AXIL_AWREADY <= '1';
S_AXIL_WREADY <= '1';
S_AXIL_BRESP <= "00";
S_AXIL_ARREADY <= '1';
S_AXIL_RRESP <= "00";
process begin
wait until rising_edge (ACLK);
if ARESETN = '0' then
S_AXIL_BVALID <= '0';
S_AXIL_RVALID <= '0';
coeff_11 <= (others=>'0');
coeff_12 <= (others=>'0');
coeff_13 <= (others=>'0');
coeff_21 <= (others=>'0');
coeff_22 <= (0=>'1',others=>'0');
coeff_23 <= (others=>'0');
coeff_31 <= (others=>'0');
coeff_32 <= (others=>'0');
coeff_33 <= (others=>'0');
shiftAmount <= to_unsigned(0,wShift);
else
if S_AXIL_RREADY = '1' then
S_AXIL_RVALID <= '0';
end if;
if S_AXIL_ARVALID = '1' then
S_AXIL_RDATA <= (others=>'0');
case (to_integer(unsigned(S_AXIL_ARADDR(5 downto 0)))) is
when 0 =>
when 4 =>
when 8 =>
when 12 =>
when 16 =>
when 20 =>
when 24 =>
when 28 =>
when 32 =>
when 36 =>
when others => null;
end case;
S_AXIL_RVALID <= '1';
end if;
if S_AXIL_BREADY = '1' then
S_AXIL_BVALID <= '';
end if;
if S_AXIL_AWVALID = '1' and S_AXIL_WVALID = '1' then
S_AXIL_BVALID <= '';
S_AXIL_RDATA <= (others=>'0');
if S_AXIL_WSTRB(0) = '1' then
case (to_integer(unsigned(S_AXIL_AWADDR(5 downto 0)))) is
when 0 =>
when 4 =>
when 8 =>
when 12 =>
when 16 =>
when 20 =>
when 24 =>
when 28 =>
when 32 =>
when 36 =>
when others => null;
end case;
end if;
end if;
end if;
end process;
@@ -0,0 +1,62 @@
S_AXIS_TREADY <= M_AXIS_TREADY or (not m_valid_sig1) or (not m_valid_sig2);
-----------------------
-- Filter Kernel
-----------------------
process
variable data_11 : signed (wPixelSigned-1 downto 0);
variable data_12 : signed (wPixelSigned-1 downto 0);
variable data_13 : signed (wPixelSigned-1 downto 0);
variable data_21 : signed (wPixelSigned-1 downto 0);
variable data_22 : signed (wPixelSigned-1 downto 0);
variable data_23 : signed (wPixelSigned-1 downto 0);
variable data_31 : signed (wPixelSigned-1 downto 0);
variable data_32 : signed (wPixelSigned-1 downto 0);
variable data_33 : signed (wPixelSigned-1 downto 0);
variable filterResult : signed (wFilterRes-1 downto 0);
begin
wait until rising_edge (ACLK);
if ARESETN = '0' then
m_valid_sig1 <= '0';
m_valid_sig2 <= '0';
else
if M_AXIS_TREADY = '1' or m_valid_sig1='0' then
data_11 := data_12;
data_12 := data_13;
data_13 := signed("0"&S_AXIS_TDATA(wPixel*3-1 downto wPixel*2));
data_21 := data_22;
data_22 := data_23;
data_23 := signed("0"&S_AXIS_TDATA(wPixel*2-1 downto wPixel*1));
data_31 := data_32;
data_32 := data_33;
data_33 := signed("0"&S_AXIS_TDATA(wPixel*1-1 downto wPixel*0));
row1Result <= resize(data_11*coeff_11,wRowProd) + resize(data_12*coeff_12,wRowProd) + resize(data_13*coeff_13,wRowProd);
row2Result <= ;
row3Result <= ;
m_last_sig1 <= S_AXIS_TLAST;
m_user_sig1 <= S_AXIS_TUSER(1);
m_valid_sig1 <= S_AXIS_TVALID;
end if;
if M_AXIS_TREADY = '1' or m_valid_sig2='0' then
filterResult := resize(row1Result,wFilterRes)+resize()+resize();
filterResult := shift_right(filterResult, to_integer());
if (filterResult < 0) then
filterResult := to_signed(0,wFilterRes);
elsif (filterResult > 255) then
filterResult := to_signed(255,wFilterRes);
end if;
M_AXIS_TDATA <= std_logic_vector(filterResult(7 downto 0));
M_AXIS_TVALID <= m_valid_sig1;
M_AXIS_TLAST <= m_last_sig1;
M_AXIS_TUSER <= m_user_sig1;
m_valid_sig2 <= m_valid_sig1;
end if;
end if;
end process;
@@ -0,0 +1,27 @@
constant wCoeff : integer := COEFF_WIDTH;
constant wShift : integer := 4;
constant wPixel : integer := 8;
constant wPixelSigned : integer := wPixel+1;
constant wRowProd : integer := wPixelSigned + wCoeff + 2;
constant wFilterRes : integer := wRowProd+1 + 2;
signal m_valid_sig1 : std_logic;
signal m_valid_sig2 : std_logic;
signal m_last_sig1 : std_logic;
signal m_user_sig1 : std_logic;
signal row1Result : signed(wRowProd-1 downto 0);
signal row2Result : signed(wRowProd-1 downto 0);
signal row3Result : signed(wRowProd-1 downto 0);
signal coeff_11 : signed(wCoeff-1 downto 0);
signal coeff_12 : signed(wCoeff-1 downto 0);
signal coeff_13 : signed(wCoeff-1 downto 0);
signal coeff_21 : signed(wCoeff-1 downto 0);
signal coeff_22 : signed(wCoeff-1 downto 0);
signal coeff_23 : signed(wCoeff-1 downto 0);
signal coeff_31 : signed(wCoeff-1 downto 0);
signal coeff_32 : signed(wCoeff-1 downto 0);
signal coeff_33 : signed(wCoeff-1 downto 0);
signal shiftAmount : unsigned(wShift-1 downto 0);
Binary file not shown.
Binary file not shown.
+348
View File
@@ -0,0 +1,348 @@
################################################################
# This is a generated script based on design: m6_sim
#
# Though there are limitations about the generated script,
# the main purpose of this utility is to make learning
# IP Integrator Tcl commands easier.
################################################################
namespace eval _tcl {
proc get_script_folder {} {
set script_path [file normalize [info script]]
set script_folder [file dirname $script_path]
return $script_folder
}
}
variable script_folder
set script_folder [_tcl::get_script_folder]
################################################################
# Check if script is running in correct Vivado version.
################################################################
set scripts_vivado_version 2023.1
set current_vivado_version [version -short]
if { [string first $scripts_vivado_version $current_vivado_version] == -1 } {
puts ""
catch {common::send_gid_msg -ssname BD::TCL -id 2041 -severity "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."}
return 1
}
################################################################
# START
################################################################
# To test this script, run the following commands from Vivado Tcl console:
# source m6_sim_script.tcl
# If there is no project opened, this script will create a
# project, but make sure you do not have an existing project
# <./myproj/project_1.xpr> in the current working folder.
set list_projs [get_projects -quiet]
if { $list_projs eq "" } {
create_project project_1 myproj -part xc7z020clg400-1
set_property BOARD_PART digilentinc.com:zybo-z7-20:part0:1.1 [current_project]
}
# CHANGE DESIGN NAME HERE
variable design_name
set design_name m6_sim
# If you do not already have an existing IP Integrator design open,
# you can create a design using the following command:
# create_bd_design $design_name
# Creating design if needed
set errMsg ""
set nRet 0
set cur_design [current_bd_design -quiet]
set list_cells [get_bd_cells -quiet]
if { ${design_name} eq "" } {
# USE CASES:
# 1) Design_name not set
set errMsg "Please set the variable <design_name> to a non-empty value."
set nRet 1
} elseif { ${cur_design} ne "" && ${list_cells} eq "" } {
# USE CASES:
# 2): Current design opened AND is empty AND names same.
# 3): Current design opened AND is empty AND names diff; design_name NOT in project.
# 4): Current design opened AND is empty AND names diff; design_name exists in project.
if { $cur_design ne $design_name } {
common::send_gid_msg -ssname BD::TCL -id 2001 -severity "INFO" "Changing value of <design_name> from <$design_name> to <$cur_design> since current design is empty."
set design_name [get_property NAME $cur_design]
}
common::send_gid_msg -ssname BD::TCL -id 2002 -severity "INFO" "Constructing design in IPI design <$cur_design>..."
} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } {
# USE CASES:
# 5) Current design opened AND has components AND same names.
set errMsg "Design <$design_name> already exists in your project, please set the variable <design_name> to another value."
set nRet 1
} elseif { [get_files -quiet ${design_name}.bd] ne "" } {
# USE CASES:
# 6) Current opened design, has components, but diff names, design_name exists in project.
# 7) No opened design, design_name exists in project.
set errMsg "Design <$design_name> already exists in your project, please set the variable <design_name> to another value."
set nRet 2
} else {
# USE CASES:
# 8) No opened design, design_name not in project.
# 9) Current opened design, has components, but diff names, design_name not in project.
common::send_gid_msg -ssname BD::TCL -id 2003 -severity "INFO" "Currently there is no design <$design_name> in project, so creating one..."
create_bd_design $design_name
common::send_gid_msg -ssname BD::TCL -id 2004 -severity "INFO" "Making design <$design_name> as current_bd_design."
current_bd_design $design_name
}
common::send_gid_msg -ssname BD::TCL -id 2005 -severity "INFO" "Currently the variable <design_name> is equal to \"$design_name\"."
if { $nRet != 0 } {
catch {common::send_gid_msg -ssname BD::TCL -id 2006 -severity "ERROR" $errMsg}
return $nRet
}
set bCheckIPsPassed 1
##################################################################
# CHECK IPs
##################################################################
set bCheckIPs 1
if { $bCheckIPs == 1 } {
set list_check_ips "\
xilinx.com:user:axis_downsizer:1.0\
xilinx.com:user:axis_linemem_single_master:1.0\
xilinx.com:user:axis_filter_dummy:1.0\
xilinx.com:user:axis_upsizer:1.0\
wg:user:clk_rst_generator:1.0\
Gehrke:user:axis_master_simmodel:1.0\
Gehrke:user:axis_slave_simmodel:1.0\
wg:user:axil_master_with_rom:1.0\
"
set list_ips_missing ""
common::send_gid_msg -ssname BD::TCL -id 2011 -severity "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ."
foreach ip_vlnv $list_check_ips {
set ip_obj [get_ipdefs -all $ip_vlnv]
if { $ip_obj eq "" } {
lappend list_ips_missing $ip_vlnv
}
}
if { $list_ips_missing ne "" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2012 -severity "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." }
set bCheckIPsPassed 0
}
}
if { $bCheckIPsPassed != 1 } {
common::send_gid_msg -ssname BD::TCL -id 2023 -severity "WARNING" "Will not continue with creation of design due to the error(s) above."
return 3
}
##################################################################
# DESIGN PROCs
##################################################################
# Hierarchical cell: SIM_Environment
proc create_hier_cell_SIM_Environment { parentCell nameHier } {
variable script_folder
if { $parentCell eq "" || $nameHier eq "" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2092 -severity "ERROR" "create_hier_cell_SIM_Environment() - Empty argument(s)!"}
return
}
# Get object for parentCell
set parentObj [get_bd_cells $parentCell]
if { $parentObj == "" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2090 -severity "ERROR" "Unable to find parent cell <$parentCell>!"}
return
}
# Make sure parentObj is hier blk
set parentType [get_property TYPE $parentObj]
if { $parentType ne "hier" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2091 -severity "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be <hier>."}
return
}
# Save current instance; Restore later
set oldCurInst [current_bd_instance .]
# Set parent object as current
current_bd_instance $parentObj
# Create cell and set as current instance
set hier_obj [create_bd_cell -type hier $nameHier]
current_bd_instance $hier_obj
# Create interface pins
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M_AXIS
create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S_AXIS
create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXIL
# Create pins
create_bd_pin -dir O -type clk M_AXIL_ACLK
create_bd_pin -dir O -type rst M_AXIL_ARESETN
# Create instance: clk_rst_generator_0, and set properties
set clk_rst_generator_0 [ create_bd_cell -type ip -vlnv wg:user:clk_rst_generator:1.0 clk_rst_generator_0 ]
set_property -dict [list \
CONFIG.HAS_CLK_INPUT {false} \
CONFIG.HAS_RESET_INPUT {false} \
CONFIG.HAS_STOP_INPUT {true} \
] $clk_rst_generator_0
# Create instance: axis_master_simmodel_0, and set properties
set axis_master_simmodel_0 [ create_bd_cell -type ip -vlnv Gehrke:user:axis_master_simmodel:1.0 axis_master_simmodel_0 ]
set_property -dict [list \
CONFIG.FILE_NAME {../../../../Moewe-192x192} \
CONFIG.NUM_LINES {192} \
CONFIG.NUM_PIX_PER_LINE {192} \
CONFIG.PIXEL_FORMAT {13} \
] $axis_master_simmodel_0
# Create instance: axis_slave_simmodel_0, and set properties
set axis_slave_simmodel_0 [ create_bd_cell -type ip -vlnv Gehrke:user:axis_slave_simmodel:1.0 axis_slave_simmodel_0 ]
set_property -dict [list \
CONFIG.FILE_NAME {../../../../tst_out} \
CONFIG.NUM_LINES {192} \
CONFIG.NUM_PIX_PER_LINE {192} \
CONFIG.PIXEL_FORMAT {13} \
] $axis_slave_simmodel_0
# Create instance: axil_master_with_rom_0, and set properties
set axil_master_with_rom_0 [ create_bd_cell -type ip -vlnv wg:user:axil_master_with_rom:1.0 axil_master_with_rom_0 ]
set_property -dict [list \
CONFIG.HAS_FINISHED_OUT {false} \
CONFIG.HAS_INTERRUPT_IN {false} \
] $axil_master_with_rom_0
# Create interface connections
connect_bd_intf_net -intf_net Conn1 [get_bd_intf_pins axil_master_with_rom_0/M_AXIL] [get_bd_intf_pins M_AXIL]
connect_bd_intf_net -intf_net axis_master_simmodel_0_M_AXIS [get_bd_intf_pins M_AXIS] [get_bd_intf_pins axis_master_simmodel_0/M_AXIS]
connect_bd_intf_net -intf_net axis_upsizer_0_M_AXIS [get_bd_intf_pins S_AXIS] [get_bd_intf_pins axis_slave_simmodel_0/S_AXIS]
# Create port connections
connect_bd_net -net axis_slave_simmodel_0_FINISHED [get_bd_pins axis_slave_simmodel_0/FINISHED] [get_bd_pins clk_rst_generator_0/stop_simulation]
connect_bd_net -net clk_rst_generator_0_clk [get_bd_pins clk_rst_generator_0/clk] [get_bd_pins M_AXIL_ACLK] [get_bd_pins axil_master_with_rom_0/M_AXIL_ACLK] [get_bd_pins axis_slave_simmodel_0/S_AXIS_ACLK] [get_bd_pins axis_master_simmodel_0/ACLK]
connect_bd_net -net clk_rst_generator_0_rst_n [get_bd_pins clk_rst_generator_0/rst_n] [get_bd_pins M_AXIL_ARESETN] [get_bd_pins axil_master_with_rom_0/M_AXIL_ARESETN] [get_bd_pins axis_slave_simmodel_0/S_AXIS_ARESETN] [get_bd_pins axis_master_simmodel_0/ARESETN]
# Restore current instance
current_bd_instance $oldCurInst
}
# Procedure to create entire design; Provide argument to make
# procedure reusable. If parentCell is "", will use root.
proc create_root_design { parentCell } {
variable script_folder
variable design_name
if { $parentCell eq "" } {
set parentCell [get_bd_cells /]
}
# Get object for parentCell
set parentObj [get_bd_cells $parentCell]
if { $parentObj == "" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2090 -severity "ERROR" "Unable to find parent cell <$parentCell>!"}
return
}
# Make sure parentObj is hier blk
set parentType [get_property TYPE $parentObj]
if { $parentType ne "hier" } {
catch {common::send_gid_msg -ssname BD::TCL -id 2091 -severity "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be <hier>."}
return
}
# Save current instance; Restore later
set oldCurInst [current_bd_instance .]
# Set parent object as current
current_bd_instance $parentObj
# Create interface ports
# Create ports
# Create instance: axis_downsizer_0, and set properties
set axis_downsizer_0 [ create_bd_cell -type ip -vlnv xilinx.com:user:axis_downsizer:1.0 axis_downsizer_0 ]
set_property CONFIG.SIZE_FACTOR {4} $axis_downsizer_0
# Create instance: axis_linemem_single_0, and set properties
set axis_linemem_single_0 [ create_bd_cell -type ip -vlnv xilinx.com:user:axis_linemem_single_master:1.0 axis_linemem_single_0 ]
set_property CONFIG.DATA_WIDTH {8} $axis_linemem_single_0
# Create instance: axis_filter_dummy_0, and set properties
set axis_filter_dummy_0 [ create_bd_cell -type ip -vlnv xilinx.com:user:axis_filter_dummy:1.0 axis_filter_dummy_0 ]
# Create instance: axis_upsizer_0, and set properties
set axis_upsizer_0 [ create_bd_cell -type ip -vlnv xilinx.com:user:axis_upsizer:1.0 axis_upsizer_0 ]
set_property CONFIG.SIZE_FACTOR {4} $axis_upsizer_0
# Create instance: SIM_Environment
create_hier_cell_SIM_Environment [current_bd_instance .] SIM_Environment
# Create interface connections
connect_bd_intf_net -intf_net axis_downsizer_0_M_AXIS [get_bd_intf_pins axis_downsizer_0/M_AXIS] [get_bd_intf_pins axis_linemem_single_0/s_axis]
connect_bd_intf_net -intf_net axis_filter_dummy_0_M_AXIS [get_bd_intf_pins axis_filter_dummy_0/M_AXIS] [get_bd_intf_pins axis_upsizer_0/S_AXIS]
connect_bd_intf_net -intf_net axis_linemem_single_0_m_axis [get_bd_intf_pins axis_linemem_single_0/m_axis] [get_bd_intf_pins axis_filter_dummy_0/S_AXIS]
connect_bd_intf_net -intf_net axis_master_simmodel_0_M_AXIS [get_bd_intf_pins axis_downsizer_0/S_AXIS] [get_bd_intf_pins SIM_Environment/M_AXIS]
connect_bd_intf_net -intf_net axis_upsizer_0_M_AXIS [get_bd_intf_pins axis_upsizer_0/M_AXIS] [get_bd_intf_pins SIM_Environment/S_AXIS]
# Create port connections
connect_bd_net -net clk_rst_generator_0_clk [get_bd_pins SIM_Environment/M_AXIL_ACLK] [get_bd_pins axis_filter_dummy_0/AXIS_ACLK] [get_bd_pins axis_linemem_single_0/aclk] [get_bd_pins axis_upsizer_0/AXIS_ACLK] [get_bd_pins axis_downsizer_0/AXIS_ACLK]
connect_bd_net -net clk_rst_generator_0_rst_n [get_bd_pins SIM_Environment/M_AXIL_ARESETN] [get_bd_pins axis_filter_dummy_0/AXIS_ARESETN] [get_bd_pins axis_linemem_single_0/aresetn] [get_bd_pins axis_upsizer_0/AXIS_ARESETN] [get_bd_pins axis_downsizer_0/AXIS_ARESETN]
# Create address segments
# Restore current instance
current_bd_instance $oldCurInst
validate_bd_design
save_bd_design
}
# End of create_root_design()
##################################################################
# MAIN FLOW
##################################################################
create_root_design ""
Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

@@ -0,0 +1,6 @@
create_clock -period 16.666 -name video_clk [get_pins -regexp .*PS/FCLK_CLK3 -hierarchical]
set_clock_groups -asynchronous -group [get_clocks clk_fpga_0] -group [get_clocks video_clk]
set_clock_groups -asynchronous -group [get_clocks clk_fpga_0] -group [get_clocks clk_fpga_3]
set_clock_groups -asynchronous -group [get_clocks clk_fpga_0] -group [get_clocks pllclk1x_pll]
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
#Switches
set_property -dict { PACKAGE_PIN G15 IOSTANDARD LVCMOS33 } [get_ports { SWITCH[0] }]; #IO_L19N_T3_VREF_35 Sch=sw[0]
set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { SWITCH[1] }]; #IO_L24P_T3_34 Sch=sw[1]
set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports { SWITCH[2] }]; #IO_L4N_T0_34 Sch=sw[2]
set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { SWITCH[3] }]; #IO_L9P_T1_DQS_34 Sch=sw[3]
#Buttons
set_property -dict { PACKAGE_PIN K18 IOSTANDARD LVCMOS33 } [get_ports { BUTTON[0] }]; #IO_L12N_T1_MRCC_35 Sch=btn[0]
set_property -dict { PACKAGE_PIN P16 IOSTANDARD LVCMOS33 } [get_ports { BUTTON[1] }]; #IO_L24N_T3_34 Sch=btn[1]
set_property -dict { PACKAGE_PIN K19 IOSTANDARD LVCMOS33 } [get_ports { BUTTON[2] }]; #IO_L10P_T1_AD11P_35 Sch=btn[2]
set_property -dict { PACKAGE_PIN Y16 IOSTANDARD LVCMOS33 } [get_ports { BUTTON[3] }]; #IO_L7P_T1_34 Sch=btn[3]
#LEDs
set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L23P_T3_35 Sch=led[0]
set_property -dict { PACKAGE_PIN M15 IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_L23N_T3_35 Sch=led[1]
set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_0_35 Sch=led[2]
set_property -dict { PACKAGE_PIN D18 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L3N_T0_DQS_AD1N_35 Sch=led[3]
#RGB LED 5 (Zybo Z7-20 only)
set_property -dict { PACKAGE_PIN Y11 IOSTANDARD LVCMOS33 } [get_ports { RGB_LED[0] }]; #IO_L18N_T2_13 Sch=led5_r
set_property -dict { PACKAGE_PIN T5 IOSTANDARD LVCMOS33 } [get_ports { RGB_LED[1] }]; #IO_L19P_T3_13 Sch=led5_g
set_property -dict { PACKAGE_PIN Y12 IOSTANDARD LVCMOS33 } [get_ports { RGB_LED[2] }]; #IO_L20P_T3_13 Sch=led5_b
#RGB LED 6
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { RGB_LED[3] }]; #IO_L18P_T2_34 Sch=led6_r
set_property -dict { PACKAGE_PIN F17 IOSTANDARD LVCMOS33 } [get_ports { RGB_LED[4] }]; #IO_L6N_T0_VREF_35 Sch=led6_g
set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { RGB_LED[5] }]; #IO_L8P_T1_AD10P_35 Sch=led6_b
#HDMI TX
set_property -dict { PACKAGE_PIN H17 IOSTANDARD TMDS_33 } [get_ports { HDMI_CLK_N }]; #IO_L13N_T2_MRCC_35 Sch=hdmi_tx_clk_n
set_property -dict { PACKAGE_PIN H16 IOSTANDARD TMDS_33 } [get_ports { HDMI_CLK_P }]; #IO_L13P_T2_MRCC_35 Sch=hdmi_tx_clk_p
set_property -dict { PACKAGE_PIN D20 IOSTANDARD TMDS_33 } [get_ports { HDMI_DATA_N[0] }]; #IO_L4N_T0_35 Sch=hdmi_tx_n[0]
set_property -dict { PACKAGE_PIN D19 IOSTANDARD TMDS_33 } [get_ports { HDMI_DATA_P[0] }]; #IO_L4P_T0_35 Sch=hdmi_tx_p[0]
set_property -dict { PACKAGE_PIN B20 IOSTANDARD TMDS_33 } [get_ports { HDMI_DATA_N[1] }]; #IO_L1N_T0_AD0N_35 Sch=hdmi_tx_n[1]
set_property -dict { PACKAGE_PIN C20 IOSTANDARD TMDS_33 } [get_ports { HDMI_DATA_P[1] }]; #IO_L1P_T0_AD0P_35 Sch=hdmi_tx_p[1]
set_property -dict { PACKAGE_PIN A20 IOSTANDARD TMDS_33 } [get_ports { HDMI_DATA_N[2] }]; #IO_L2N_T0_AD8N_35 Sch=hdmi_tx_n[2]
set_property -dict { PACKAGE_PIN B19 IOSTANDARD TMDS_33 } [get_ports { HDMI_DATA_P[2] }]; #IO_L2P_T0_AD8P_35 Sch=hdmi_tx_p[2]
+117
View File
@@ -0,0 +1,117 @@
------------------------------------------------------------------------------
-- axis_video_filter.vhd - entity/architecture pair
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity axis_video_filter is
generic (
COEFF_WIDTH : integer := 8
);
port (
ACLK : in std_logic;
ARESETN : in std_logic;
-- AXI Streaming Target Port (from linemem)
S_AXIS_TVALID : in std_logic := '0';
S_AXIS_TDATA : in std_logic_vector(23 downto 0);
S_AXIS_TLAST : in std_logic := '0';
S_AXIS_TREADY : out std_logic;
S_AXIS_TUSER : in std_logic_vector(2 downto 0);
-- AXI Streaming Initiator Port
M_AXIS_TVALID : out std_logic;
M_AXIS_TDATA : out std_logic_vector(7 downto 0);
M_AXIS_TLAST : out std_logic;
M_AXIS_TREADY : in std_logic := '1';
M_AXIS_TUSER : out std_logic;
-- AXI-Lite Slave Interface (from/to CPU)
S_AXIL_AWADDR : in std_logic_vector(14 downto 0) := (others=>'0');
S_AXIL_AWVALID : in std_logic := '0';
S_AXIL_AWREADY : out std_logic;
S_AXIL_WDATA : in std_logic_vector(31 downto 0) := (others=>'0');
S_AXIL_WVALID : in std_logic := '0';
S_AXIL_WREADY : out std_logic;
S_AXIL_WSTRB : in std_logic_vector( 3 downto 0) := (others=>'0');
S_AXIL_BVALID : out std_logic;
S_AXIL_BREADY : in std_logic := '1';
S_AXIL_BRESP : out std_logic_vector( 1 downto 0);
S_AXIL_ARADDR : in std_logic_vector(14 downto 0) := (others=>'0');
S_AXIL_ARVALID : in std_logic := '0';
S_AXIL_ARREADY : out std_logic;
S_AXIL_RDATA : out std_logic_vector(31 downto 0);
S_AXIL_RVALID : out std_logic;
S_AXIL_RREADY : in std_logic := '1';
S_AXIL_RRESP : out std_logic_vector( 1 downto 0)
);
end;
architecture rtl of axis_video_filter is
constant wCoeff : integer := COEFF_WIDTH;
constant wShift : integer := 4;
constant wPixel : integer := 8;
constant wPixelSigned : integer := wPixel+1;
constant wRowProd : integer := wPixelSigned + wCoeff + 2;
constant wFilterRes : integer := wRowProd+1 + 2;
begin
S_AXIS_TREADY <= M_AXIS_TREADY;
-----------------------
-- Filter Kernel
-----------------------
process
begin
end process;
-----------------------
-- AXI-Lite Interface
-----------------------
S_AXIL_AWREADY <= '1';
S_AXIL_WREADY <= '1';
S_AXIL_BRESP <= "00";
S_AXIL_ARREADY <= '1';
S_AXIL_RRESP <= "00";
process begin
wait until rising_edge (ACLK);
if ARESETN = '0' then
S_AXIL_BVALID <= '0';
S_AXIL_RVALID <= '0';
else
if S_AXIL_RREADY = '1' then
S_AXIL_RVALID <= '0';
end if;
if S_AXIL_ARVALID = '1' then
S_AXIL_RDATA <= (others=>'0');
S_AXIL_RVALID <= '1';
end if;
if S_AXIL_BREADY = '1' then
S_AXIL_BVALID <= '0';
end if;
if S_AXIL_AWVALID = '1' and S_AXIL_WVALID = '1' then
S_AXIL_BVALID <= '1';
end if;
end if;
end process;
end;
+3
View File
@@ -0,0 +1,3 @@
@echo off
echo:
for %%i in (*.stm) do stm2mem %%i & echo: & echo: & echo:
+203
View File
@@ -0,0 +1,203 @@
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "opencv2/opencv.hpp"
#include <iostream>
#include <thread>
#include "gip.h"
// **********************************************************************
//
// Frame-Interrupt Thread der HDMI-Ausgabe des IPs ZYNQ-BASE-HDMI
//
// Alle 60 Frames (und damit jede Sekunde) wird die Farbe einer
// der RGB-LEDs auf dem Zybo-Board geändert
//
// **********************************************************************
void blinkRGBLED()
{
int fdZynqBase = open ("/dev/uio0", O_RDWR);
PGIP_ZYNQ_BASE zynqBase= (PGIP_ZYNQ_BASE) mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fdZynqBase, 0);
int i = 0;
int col = 0;
int pending;
int reenable=1;
// Initialisierung:
// Interrupts freigeben, INT-Status loeschen und Interrupt-verarbeitung im UIO-Treiber aktivieren
zynqBase->InterruptStatus = 0;
zynqBase->InterruptEnable = 1;
write(fdZynqBase,&reenable,4);
// Hier die eigentliche ISR:
// INTs zaehlen und alle 60 INTs die Farbe einer der RGB-LEDs aendern
while(1) {
read(fdZynqBase,&pending,4);
write(fdZynqBase,&reenable,4);
zynqBase->InterruptStatus = 0;
i++;
if (i==60) {
i=0;
zynqBase->Board_IO &= 0x00FFFFFF;
zynqBase->Board_IO |= 1<<(24+col);
col = (col+1)%3;
}
}
}
// **********************************************************************
//
// Thread zur Demonstration des Verhaltens eines Video-Streaming-IPs
// mit Ausgabe der Input- und Output-Bilder ueber OpenCV-Fenster
//
// Bei CIF-Aufloesung (352x288) wird annaehernd Echtzeit erreicht
// Bei Verwendung hoeherer Aufloesungen ist die Ausgabe, bedingt durch OpenCV, deutlich verlangsamt
//
// **********************************************************************
int videoDemo()
{
int currFrame = 0; // Zaehler fuer aktuell verwendetes Bild
int videoNum = 6; // Auswahl der Videosequenz - aus den nachfolgend aufgefuehrten
const std::string videoFiles[9] = {
"/home/user/Videos/testseq/MobileCalendar",
"/home/user/Videos/testseq/Football",
"/home/user/Videos/testseq/acht_cam_",
"/home/user/Videos/testseq/acht_bev_",
"/home/user/Videos/testseq/BetesPasBetes_CIF",
"/home/user/Videos/testseq/Football_CIF",
"/home/user/Videos/testseq/MobileCalendar_CIF",
"/home/user/Videos/testseq/FlowerGarden_CIF",
"/home/user/Videos/testseq/LePoint_CIF",
};
std::string fn = videoFiles[videoNum]+std::to_string(currFrame++)+".jpg"; // Filename
cv::Mat imgJpg = cv::imread(fn,cv::IMREAD_GRAYSCALE); // Erstes Bild lesen
char c = 0;
int pending;
int reenable=1;
// Memory-Mapping durchfuehren
int fdPrivateMemory = open ("/dev/uio16", O_RDWR);
uint8_t* privMem = (uint8_t*) mmap(NULL, 0x8000000, PROT_READ|PROT_WRITE, MAP_SHARED, fdPrivateMemory, 0); // Request 128 MB
int fdMm2vs = open ("/dev/uio1", O_RDWR);
PGIP_AXI_2D_MM2VS mmvs= (PGIP_AXI_2D_MM2VS) mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fdMm2vs, 0);
int fdFilter = open ("/dev/uio2", O_RDWR);
int32_t* filter = (int32_t*) mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fdFilter, 0);
// Falls MMVS bereits aktiv ist, sollte er zunächst alle laufenden Requests zuende abarbeiten
// Schaltet man zunaechst die Zufuehrung von Daten (MM2VS) ab, können auch die Streaming-FIFOs leerlaufen
mmvs->MM2VS_Control = 0;
usleep(100000);
mmvs->VS2MM_Control = 0;
usleep(100000);
if (!imgJpg.empty()) { // Konnte das 1. Bild erfolgreich gelesen werden?
// Falls nein, brauchen wir gar nicht weitermachen und beenden den Thread
cv::Mat imgGrayIn(imgJpg.size(),CV_8UC1,&privMem[0]); // Speicher fuer Eingangsbild einer OpenCV-Mat zuordnen
cv::Mat imgGrayOut(imgJpg.size(),CV_8UC1,&privMem[0x400000]); // dto. fuer Ausgangsbild
mmvs->InterruptEnable = (1<<1); // VS2MM INT freigeben
write(fdMm2vs,&reenable,4);
mmvs->MM2VS_StartAddress = 0x30000000; // Adressierungsparameter fuer Eingangsbild setzen
mmvs->MM2VS_HorizontalBytes = imgJpg.cols;
mmvs->MM2VS_Stride=imgJpg.cols;
mmvs->MM2VS_VerticalLines=imgJpg.rows;
mmvs->MM2VS_Control |= (0x0<<12); // ARCACHE
mmvs->VS2MM_StartAddress = 0x30400000; // Adressierungsparameter fuer Ausgangsbild setzen
mmvs->VS2MM_HorizontalBytes = imgJpg.cols;
mmvs->VS2MM_Stride=imgJpg.cols;
mmvs->VS2MM_VerticalLines=imgJpg.rows;
mmvs->VS2MM_InterruptLine = 1;
mmvs->VS2MM_Control |= (0x0<<12); // AWCACHE
mmvs->VS2MM_Control |= (1<<1); // Synchronize with Start of Frame (e.g. TUSER=1)
mmvs->InterruptStatus = 0; // INT Status im MMVS loeschen
mmvs->VS2MM_Control |= (1<<0); // Start VS2MM
mmvs->MM2VS_Control |= (1<<0); // Start MM2VS
// Filter Coefficients
filter[0]= -1;
filter[1]= -2;
filter[2]= -1;
filter[3]= 0;
filter[4]= 0;
filter[5]= 0;
filter[6]= 1;
filter[7]= 2;
filter[8]= 1;
filter[9]= 0;
//
// Schleife durch alle Bilder der Videodateien (Abbruch mit ESC-Taste)
//
while(c!=27) { // Press ESC on keyboard to exit
fn = videoFiles[videoNum]+std::to_string(currFrame++)+".jpg";
imgJpg = cv::imread(fn,cv::IMREAD_GRAYSCALE);
if (imgJpg.empty()) {
currFrame = 0;
} else {
memcpy(imgGrayIn.data,imgJpg.data,imgJpg.cols*imgJpg.rows);
read(fdMm2vs,&pending,4); // Auf VS2MM INT warten
write(fdMm2vs,&reenable,4); // INT wieder aktivieren
mmvs->InterruptStatus = 0;
cv::imshow( "In", imgGrayIn ); // Display input image
cv::imshow( "Out", imgGrayOut); // Display output image
//fn = videoFiles[videoNum]+std::to_string(currFrame)+"_out.jpg";
//cv::imwrite(fn,imgGrayOut);
c=(char)cv::waitKey(1); // Press ESC on keyboard to exit
}
}
cv::destroyAllWindows(); // Close all OpenCV windows
}
// Memory-Streaming ausschalten (wir wollen schliesslich nicht unnoetig die anderen Komponenten ausbremsen)
mmvs->MM2VS_Control = 0;
usleep(100000);
mmvs->VS2MM_Control = 0;
usleep(100000);
return 0;
}
// **********************************************************************
//
// main()
//
// **********************************************************************
int main(int argc, char** argv)
{
std::thread t1(blinkRGBLED); // Threads anlegen
std::thread t2(videoDemo);
//t1.join(); // Der Blink-Thread wird nie beendet, also brauchen wir darauf auch nicht warten
t2.join(); // Wenn der OpenCV-Thread beendet wird, sind wir fertig
return 0;
}
+21
View File
@@ -0,0 +1,21 @@
0100001111000000000000000000000000000001
0000000000000000000000001111111100001111
0100001111000000000000000000010000000001
0000000000000000000000001111111000001111
0100001111000000000000000000100000000001
0000000000000000000000001111111100001111
0100001111000000000000000000110000000001
0000000000000000000000000000000000001111
0100001111000000000000000001000000000001
0000000000000000000000000000000000001111
0100001111000000000000000001010000000001
0000000000000000000000000000000000001111
0100001111000000000000000001100000000001
0000000000000000000000000000000100001111
0100001111000000000000000001110000000001
0000000000000000000000000000001000001111
0100001111000000000000000010000000000001
0000000000000000000000000000000100001111
0100001111000000000000000010010000000001
0000000000000000000000000000000000001111
0000000000000000000000000000000000000000
+10
View File
@@ -0,0 +1,10 @@
wal 0x43c00000 0x000000FF # Start Filterkoeffizienten
wal 0x43c00004 0x000000FE
wal 0x43c00008 0x000000FF
wal 0x43c0000c 0x00000000
wal 0x43c00010 0x00000000
wal 0x43c00014 0x00000000
wal 0x43c00018 0x00000001
wal 0x43c0001C 0x00000002
wal 0x43c00020 0x00000001 # Ende Filterkoeffizienten
wal 0x43c00024 0x00000000 # ShiftAmount
Binary file not shown.