Commit 7502e474 authored by Jaco Hofmann's avatar Jaco Hofmann
Browse files

Use the dedicated Xilinx MSIx protocol to send interrupts

parent d600730e
Pipeline #577 passed with stage
in 8 minutes and 27 seconds
......@@ -122,8 +122,6 @@ namespace eval ::tapasco::ip {
puts "Connecting clock of type $main_clk as main clock -> $clk"
connect_bd_net [get_bd_pins $clk] [get_bd_pins $name/aclk]
save_bd_design
set i 1
foreach c {host design mem} {
if {$c != $main_clk} {
......
This diff is collapsed.
set_false_path -through [get_ports -scoped_to_current_instance interrupt*]
##
## set properties to help out clock domain crossing analysis
##
set s_clk [get_clocks -of_objects [get_ports -scoped_to_current_instance S_AXI_ACLK]]
set m_clk [get_clocks -of_object [get_ports -scoped_to_current_instance design_clk]]
set_max_delay -from [filter [all_fanout -from [get_ports -scoped_to_current_instance S_AXI_ACLK] -flat -endpoints_only] {IS_LEAF}] -to [filter [all_fanout -from [get_ports -scoped_to_current_instance design_clk] -flat -only_cells] {IS_SEQUENTIAL && (NAME !~ *dout_i_reg[*])}] -datapath_only [get_property -min PERIOD $s_clk]
set_max_delay -from [filter [all_fanout -from [get_ports -scoped_to_current_instance design_clk] -flat -endpoints_only] {IS_LEAF}] -to [filter [all_fanout -from [get_ports -scoped_to_current_instance S_AXI_ACLK] -flat -only_cells] {IS_SEQUENTIAL && (NAME !~ *dout_i_reg[*])}] -datapath_only [get_property -min PERIOD $m_clk]
set_false_path -through [get_ports -scoped_to_current_instance -filter {NAME =~ design_rst}] -to [filter [get_cells -hier -filter {NAME =~ *reset_hold_reg*}] {IS_SEQUENTIAL}]
set_false_path -through [get_ports -scoped_to_current_instance -filter {NAME =~ design_rst}] -to [filter [get_cells -hier -filter {NAME =~ *sGEnqPtr*}] {IS_SEQUENTIAL}]
set_false_path -through [get_ports -scoped_to_current_instance -filter {NAME =~ design_rst}] -to [filter [get_cells -hier -filter {NAME =~ *dGDeqPtr*}] {IS_SEQUENTIAL}]
set_false_path -through [get_ports -scoped_to_current_instance -filter {NAME =~ design_rst}] -to [filter [get_cells -hier -filter {NAME =~ *sSyncReg*}] {IS_SEQUENTIAL}]
set_false_path -through [get_ports -scoped_to_current_instance -filter {NAME =~ design_rst}] -to [filter [get_cells -hier -filter {NAME =~ *dSyncReg*}] {IS_SEQUENTIAL}]
set_false_path -through [get_ports -scoped_to_current_instance -filter {NAME =~ design_rst}] -to [filter [get_cells -hier -filter {NAME =~ *dEnqPtr*}] {IS_SEQUENTIAL}]
set_false_path -through [get_ports -scoped_to_current_instance -filter {NAME =~ design_rst}] -to [filter [get_cells -hier -filter {NAME =~ *dEnqToggle*}] {IS_SEQUENTIAL}]
set_false_path -through [get_ports -scoped_to_current_instance -filter {NAME =~ design_rst}] -to [filter [get_cells -hier -filter {NAME =~ *dDeqToggle*}] {IS_SEQUENTIAL}]
set_false_path -through [get_ports -scoped_to_current_instance -filter {NAME =~ design_rst}] -to [filter [get_cells -hier -filter {NAME =~ *dNotEmpty*}] {IS_SEQUENTIAL}]
set_false_path -through [get_ports -scoped_to_current_instance -filter {NAME =~ design_rst}] -to [filter [get_cells -hier -filter {NAME =~ *dLastState*}] {IS_SEQUENTIAL}]
\ No newline at end of file
// Copyright (c) 2000-2012 Bluespec, Inc.
// Copyright (c) 2000-2013 Bluespec, Inc.
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
......@@ -35,124 +34,97 @@
`define BSV_RESET_EDGE negedge
`endif
`ifdef BSV_ASYNC_RESET
`define BSV_ARESET_EDGE_META or `BSV_RESET_EDGE RST
`else
`define BSV_ARESET_EDGE_META
`endif
`ifdef BSV_RESET_FIFO_HEAD
`define BSV_ARESET_EDGE_HEAD `BSV_ARESET_EDGE_META
`else
`define BSV_ARESET_EDGE_HEAD
`endif
// Depth 1 FIFO
module FIFO1(CLK,
RST,
D_IN,
ENQ,
FULL_N,
D_OUT,
DEQ,
EMPTY_N,
CLR
);
parameter width = 1;
parameter guarded = 1;
input CLK;
input RST;
input [width - 1 : 0] D_IN;
input ENQ;
input DEQ;
input CLR ;
output FULL_N;
output [width - 1 : 0] D_OUT;
output EMPTY_N;
reg [width - 1 : 0] D_OUT;
reg empty_reg ;
assign EMPTY_N = empty_reg ;
`ifdef BSV_NO_INITIAL_BLOCKS
`else // not BSV_NO_INITIAL_BLOCKS
// synopsys translate_off
initial
begin
D_OUT = {((width + 1)/2) {2'b10}} ;
empty_reg = 1'b0 ;
end // initial begin
// synopsys translate_on
`endif // BSV_NO_INITIAL_BLOCKS
assign FULL_N = !empty_reg;
always@(posedge CLK `BSV_ARESET_EDGE_META)
//
// Transfer takes 2 dCLK to see data,
// sRDY recovers takes 2 dCLK + 2 sCLK
module SyncHandshake(
sCLK,
sRST,
dCLK,
sEN,
sRDY,
dPulse
);
parameter init = 1'b0;
parameter delayreturn = 1'b0;
// Source clock port signal
input sCLK ;
input sRST ;
input sEN ;
output sRDY ;
// Destination clock port signal
input dCLK ;
output dPulse ;
// Flops to hold data
reg dSyncReg1, dSyncReg2 ;
reg dLastState ;
reg sToggleReg ;
reg sSyncReg1, sSyncReg2 ;
// Output signal
assign dPulse = dSyncReg2 != dLastState ;
assign sRDY = sSyncReg2 == sToggleReg;
wire ackValue = delayreturn ? dLastState : dSyncReg2 ;
always @(posedge sCLK or `BSV_RESET_EDGE sRST)
begin
if (RST == `BSV_RESET_VALUE)
begin
empty_reg <= `BSV_ASSIGNMENT_DELAY 1'b0;
end // if (RST == `BSV_RESET_VALUE)
if (sRST == `BSV_RESET_VALUE)
begin
sSyncReg1 <= `BSV_ASSIGNMENT_DELAY ! init ; // Reset hi so sRDY is low during reset
sSyncReg2 <= `BSV_ASSIGNMENT_DELAY ! init ;
sToggleReg <= `BSV_ASSIGNMENT_DELAY init ;
end
else
begin
if (CLR)
begin
empty_reg <= `BSV_ASSIGNMENT_DELAY 1'b0;
end // if (CLR)
else if (ENQ)
begin
empty_reg <= `BSV_ASSIGNMENT_DELAY 1'b1;
end // if (ENQ)
else if (DEQ)
// hadshake return synchronizer
sSyncReg1 <= `BSV_ASSIGNMENT_DELAY ackValue ;// clock domain crossing
sSyncReg2 <= `BSV_ASSIGNMENT_DELAY sSyncReg1 ;
// Pulse send
if ( sEN )
begin
empty_reg <= `BSV_ASSIGNMENT_DELAY 1'b0;
end // if (DEQ)
end // else: !if(RST == `BSV_RESET_VALUE)
end // always@ (posedge CLK or `BSV_RESET_EDGE RST)
sToggleReg <= `BSV_ASSIGNMENT_DELAY ! sToggleReg ;
end // if ( sEN )
end
end // always @ (posedge sCLK or `BSV_RESET_EDGE sRST)
always@(posedge CLK `BSV_ARESET_EDGE_HEAD)
always @(posedge dCLK or `BSV_RESET_EDGE sRST)
begin
`ifdef BSV_RESET_FIFO_HEAD
if (RST == `BSV_RESET_VALUE)
if (sRST == `BSV_RESET_VALUE)
begin
D_OUT <= `BSV_ASSIGNMENT_DELAY {width {1'b0}} ;
dSyncReg1 <= `BSV_ASSIGNMENT_DELAY init;
dSyncReg2 <= `BSV_ASSIGNMENT_DELAY init;
dLastState <= `BSV_ASSIGNMENT_DELAY init ;
end
else
`endif
begin
if (ENQ)
D_OUT <= `BSV_ASSIGNMENT_DELAY D_IN;
end // else: !if(RST == `BSV_RESET_VALUE)
end // always@ (posedge CLK or `BSV_RESET_EDGE RST)
dSyncReg1 <= `BSV_ASSIGNMENT_DELAY sToggleReg ;// domain crossing
dSyncReg2 <= `BSV_ASSIGNMENT_DELAY dSyncReg1 ;
dLastState <= `BSV_ASSIGNMENT_DELAY dSyncReg2 ;
end
end // always @ (posedge dCLK or `BSV_RESET_EDGE sRST)
`ifdef BSV_NO_INITIAL_BLOCKS
`else // not BSV_NO_INITIAL_BLOCKS
// synopsys translate_off
always@(posedge CLK)
begin: error_checks
reg deqerror, enqerror ;
initial
begin
dSyncReg1 = init ;
dSyncReg2 = init ;
dLastState = init ;
deqerror = 0;
enqerror = 0;
if (RST == ! `BSV_RESET_VALUE)
begin
if ( ! empty_reg && DEQ )
begin
deqerror = 1 ;
$display( "Warning: FIFO1: %m -- Dequeuing from empty fifo" ) ;
end
if ( ! FULL_N && ENQ && (!DEQ || guarded) )
begin
enqerror = 1 ;
$display( "Warning: FIFO1: %m -- Enqueuing to a full fifo" ) ;
end
end // if (RST == ! `BSV_RESET_VALUE)
end
// synopsys translate_on
sToggleReg = init ;
sSyncReg1 = ! init ;
sSyncReg2 = ! init ;
endmodule
end // initial begin
// synopsys translate_on
`endif // BSV_NO_INITIAL_BLOCKS
endmodule // HandshakeSync
This diff is collapsed.
......@@ -102,24 +102,24 @@
puts "Connecting [llength $irqs] interrupts .."
# create hierarchical ports
set s_axi [create_bd_intf_pin -mode Slave -vlnv [tapasco::ip::get_vlnv "aximm_intf"] "S_INTC"]
set msix_interface [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:pcie3_cfg_msix_rtl:1.0 "M_MSIX"]
set aclk [tapasco::subsystem::get_port "host" "clk"]
set ic_aresetn [tapasco::subsystem::get_port "host" "rst" "interconnect"]
set p_aresetn [tapasco::subsystem::get_port "host" "rst" "peripheral" "resetn"]
set design_aclk [tapasco::subsystem::get_port "design" "clk"]
set design_aresetn [tapasco::subsystem::get_port "design" "rst" "peripheral" "resetn"]
set dma_irq_read [create_bd_pin -type "intr" -dir I "dma_irq_read"]
set dma_irq_write [create_bd_pin -type "intr" -dir I "dma_irq_write"]
set m_axi [create_bd_intf_pin -mode Master -vlnv [tapasco::ip::get_vlnv "aximm_intf"] "M_MSIX"]
set num_irqs_threadpools [::tapasco::get_platform_num_slots]
set num_irqs [expr $num_irqs_threadpools + 4]
set irq_concat_ss [tapasco::ip::create_xlconcat "interrupt_concat" 8]
set irq_concat_ss [tapasco::ip::create_xlconcat "interrupt_concat" 4]
# create MSIX interrupt controller
set msix_intr_ctrl [tapasco::ip::create_msix_intr_ctrl "msix_intr_ctrl"]
connect_bd_net [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "dout"}] [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "interrupt"}]
connect_bd_net [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "dout"}] [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "interrupt_pcie"}]
connect_bd_intf_net [get_bd_intf_pins -of_objects $msix_intr_ctrl -filter {NAME == "M_AXI"}] $m_axi
connect_bd_intf_net $msix_interface [get_bd_intf_pins msix_intr_ctrl/msix]
connect_bd_net $dma_irq_read [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "In0"}]
connect_bd_net $dma_irq_write [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "In1"}]
......@@ -128,20 +128,20 @@
connect_bd_net [get_bd_pin -of_object $irq_unused -filter {NAME == "dout"}] [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "In2"}]
connect_bd_net [get_bd_pin -of_object $irq_unused -filter {NAME == "dout"}] [get_bd_pin -of_objects $irq_concat_ss -filter {NAME == "In3"}]
set irq_concat_design [tapasco::ip::create_xlconcat "interrupt_concat_design" 4]
for {set i 0} {$i < 4} {incr i} {
set port [create_bd_pin -from 31 -to 0 -dir I -type intr "intr_$i"]
connect_bd_net $port [get_bd_pin $irq_concat_ss/[format "In%d" [expr "$i + 4"]]]
connect_bd_net $port [get_bd_pin -of_objects $irq_concat_design -filter "NAME == In$i"]
}
connect_bd_net [get_bd_pin -of_objects $irq_concat_design -filter {NAME == "dout"}] [get_bd_pin -of_objects $msix_intr_ctrl -filter {NAME == "interrupt_design"}]
# connect internal clocks
connect_bd_net $aclk [get_bd_pins -of_objects [get_bd_cells -filter {VLNV !~ "*:tapasco:*"}] -filter {TYPE == "clk" && DIR == "I"}]
# connect internal interconnect resets
set ic_resets [get_bd_pins -of_objects [get_bd_cells -filter {VLNV =~ "*:axi_interconnect:*"}] -filter {NAME == "ARESETN"}]
if {[llength $ic_resets] > 0} { connect_bd_net $ic_aresetn $ic_resets }
# connect internal peripheral resets
set p_resets [get_bd_pins -of_objects [get_bd_cells -filter {VLNV !~ "*:tapasco:*"}] -filter {TYPE == rst && DIR == I && NAME != "ARESETN"}]
puts "connect_bd_net $p_aresetn $p_resets"
connect_bd_net $p_aresetn $p_resets
connect_bd_net $aclk [get_bd_pins -of_objects $msix_intr_ctrl -filter {NAME == "S_AXI_ACLK"}]
connect_bd_net $design_aclk [get_bd_pins -of_objects $msix_intr_ctrl -filter {NAME == "design_clk"}]
connect_bd_net $p_aresetn [get_bd_pins -of_objects $msix_intr_ctrl -filter {NAME == "S_AXI_ARESETN"}]
connect_bd_net $design_aresetn [get_bd_pins -of_objects $msix_intr_ctrl -filter {NAME == "design_rst"}]
# connect S_AXI
connect_bd_intf_net $s_axi [get_bd_intf_pins -of_objects $msix_intr_ctrl -filter {NAME == "S_AXI"}]
......@@ -263,17 +263,19 @@
# create hierarchical ports
set s_axi [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 "S_HOST"]
set s_msix [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:aximm_rtl:1.0 "S_MSIX"]
set m_arch [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_ARCH"]
set m_intc [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_INTC"]
set m_tapasco [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_TAPASCO"]
set m_dma [create_bd_intf_pin -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 "M_DMA"]
set pcie_aclk [create_bd_pin -type "clk" -dir "O" "pcie_aclk"]
set pcie_aresetn [create_bd_pin -type "rst" -dir "O" "pcie_aresetn"]
set msix_interface [create_bd_intf_pin -mode Slave -vlnv xilinx.com:interface:pcie3_cfg_msix_rtl:1.0 "S_MSIX"]
# create instances of cores: PCIe core, mm_to_lite
set pcie [create_pcie_core]
connect_bd_intf_net $msix_interface [get_bd_intf_pins $pcie/pcie_cfg_msix]
# FIXME are the default settings for the IC ok?
set out_ic [tapasco::ip::create_axi_sc "out_ic" 1 4]
tapasco::ip::connect_sc_default_clocks $out_ic "host"
......@@ -284,7 +286,6 @@
tapasco::ip::connect_sc_default_clocks $in_ic "host"
connect_bd_intf_net [get_bd_intf_pins S_HOST] [get_bd_intf_pins $in_ic/S00_AXI]
connect_bd_intf_net [get_bd_intf_pins S_MSIX] [get_bd_intf_pins $in_ic/S01_AXI]
connect_bd_intf_net [get_bd_intf_pins -of_object $in_ic -filter { MODE == Master }] \
[get_bd_intf_pins -regexp $pcie/S_AXI(_B)?]
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment