commit c074971ad6d856896ba1a533b9955e3188aa0bf8 Author: Sergiusz 'q3k' BazaƄski Date: Wed Nov 18 12:56:40 2015 +0100 Initial commit. diff --git a/bd/bd.tcl b/bd/bd.tcl new file mode 100644 index 0000000..4804aeb --- /dev/null +++ b/bd/bd.tcl @@ -0,0 +1,86 @@ + +proc init { cellpath otherInfo } { + + set cell_handle [get_bd_cells $cellpath] + set all_busif [get_bd_intf_pins $cellpath/*] + set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH] + set full_sbusif_list [list ] + + foreach busif $all_busif { + if { [string equal -nocase [get_property MODE $busif] "slave"] == 1 } { + set busif_param_list [list] + set busif_name [get_property NAME $busif] + if { [lsearch -exact -nocase $full_sbusif_list $busif_name ] == -1 } { + continue + } + foreach tparam $axi_standard_param_list { + lappend busif_param_list "C_${busif_name}_${tparam}" + } + bd::mark_propagate_only $cell_handle $busif_param_list + } + } +} + + +proc pre_propagate {cellpath otherInfo } { + + set cell_handle [get_bd_cells $cellpath] + set all_busif [get_bd_intf_pins $cellpath/*] + set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH] + + foreach busif $all_busif { + if { [string equal -nocase [get_property CONFIG.PROTOCOL $busif] "AXI4"] != 1 } { + continue + } + if { [string equal -nocase [get_property MODE $busif] "master"] != 1 } { + continue + } + + set busif_name [get_property NAME $busif] + foreach tparam $axi_standard_param_list { + set busif_param_name "C_${busif_name}_${tparam}" + + set val_on_cell_intf_pin [get_property CONFIG.${tparam} $busif] + set val_on_cell [get_property CONFIG.${busif_param_name} $cell_handle] + + if { [string equal -nocase $val_on_cell_intf_pin $val_on_cell] != 1 } { + if { $val_on_cell != "" } { + set_property CONFIG.${tparam} $val_on_cell $busif + } + } + } + } +} + + +proc propagate {cellpath otherInfo } { + + set cell_handle [get_bd_cells $cellpath] + set all_busif [get_bd_intf_pins $cellpath/*] + set axi_standard_param_list [list ID_WIDTH AWUSER_WIDTH ARUSER_WIDTH WUSER_WIDTH RUSER_WIDTH BUSER_WIDTH] + + foreach busif $all_busif { + if { [string equal -nocase [get_property CONFIG.PROTOCOL $busif] "AXI4"] != 1 } { + continue + } + if { [string equal -nocase [get_property MODE $busif] "slave"] != 1 } { + continue + } + + set busif_name [get_property NAME $busif] + foreach tparam $axi_standard_param_list { + set busif_param_name "C_${busif_name}_${tparam}" + + set val_on_cell_intf_pin [get_property CONFIG.${tparam} $busif] + set val_on_cell [get_property CONFIG.${busif_param_name} $cell_handle] + + if { [string equal -nocase $val_on_cell_intf_pin $val_on_cell] != 1 } { + #override property of bd_interface_net to bd_cell -- only for slaves. May check for supported values.. + if { $val_on_cell_intf_pin != "" } { + set_property CONFIG.${busif_param_name} $val_on_cell_intf_pin $cell_handle + } + } + } + } +} + diff --git a/component.xml b/component.xml new file mode 100644 index 0000000..9e72fb8 --- /dev/null +++ b/component.xml @@ -0,0 +1,2164 @@ + + + user.org + user + ledmatrix_v1_0 + 1.0 + + + m00_axi + + + + + + + + + AWID + + + m00_axi_awid + + + + + AWADDR + + + m00_axi_awaddr + + + + + AWLEN + + + m00_axi_awlen + + + + + AWSIZE + + + m00_axi_awsize + + + + + AWBURST + + + m00_axi_awburst + + + + + AWLOCK + + + m00_axi_awlock + + + + + AWCACHE + + + m00_axi_awcache + + + + + AWPROT + + + m00_axi_awprot + + + + + AWQOS + + + m00_axi_awqos + + + + + AWUSER + + + m00_axi_awuser + + + + + AWVALID + + + m00_axi_awvalid + + + + + AWREADY + + + m00_axi_awready + + + + + WDATA + + + m00_axi_wdata + + + + + WSTRB + + + m00_axi_wstrb + + + + + WLAST + + + m00_axi_wlast + + + + + WUSER + + + m00_axi_wuser + + + + + WVALID + + + m00_axi_wvalid + + + + + WREADY + + + m00_axi_wready + + + + + BID + + + m00_axi_bid + + + + + BRESP + + + m00_axi_bresp + + + + + BUSER + + + m00_axi_buser + + + + + BVALID + + + m00_axi_bvalid + + + + + BREADY + + + m00_axi_bready + + + + + ARID + + + m00_axi_arid + + + + + ARADDR + + + m00_axi_araddr + + + + + ARLEN + + + m00_axi_arlen + + + + + ARSIZE + + + m00_axi_arsize + + + + + ARBURST + + + m00_axi_arburst + + + + + ARLOCK + + + m00_axi_arlock + + + + + ARCACHE + + + m00_axi_arcache + + + + + ARPROT + + + m00_axi_arprot + + + + + ARQOS + + + m00_axi_arqos + + + + + ARUSER + + + m00_axi_aruser + + + + + ARVALID + + + m00_axi_arvalid + + + + + ARREADY + + + m00_axi_arready + + + + + RID + + + m00_axi_rid + + + + + RDATA + + + m00_axi_rdata + + + + + RRESP + + + m00_axi_rresp + + + + + RLAST + + + m00_axi_rlast + + + + + RUSER + + + m00_axi_ruser + + + + + RVALID + + + m00_axi_rvalid + + + + + RREADY + + + m00_axi_rready + + + + + + s00_axi + + + + + + + + + AWADDR + + + s00_axi_awaddr + + + + + AWPROT + + + s00_axi_awprot + + + + + AWVALID + + + s00_axi_awvalid + + + + + AWREADY + + + s00_axi_awready + + + + + WDATA + + + s00_axi_wdata + + + + + WSTRB + + + s00_axi_wstrb + + + + + WVALID + + + s00_axi_wvalid + + + + + WREADY + + + s00_axi_wready + + + + + BRESP + + + s00_axi_bresp + + + + + BVALID + + + s00_axi_bvalid + + + + + BREADY + + + s00_axi_bready + + + + + ARADDR + + + s00_axi_araddr + + + + + ARPROT + + + s00_axi_arprot + + + + + ARVALID + + + s00_axi_arvalid + + + + + ARREADY + + + s00_axi_arready + + + + + RDATA + + + s00_axi_rdata + + + + + RRESP + + + s00_axi_rresp + + + + + RVALID + + + s00_axi_rvalid + + + + + RREADY + + + s00_axi_rready + + + + + + m00_axi_aresetn + + + + + + + RST + + + m00_axi_aresetn + + + + + + POLARITY + ACTIVE_LOW + + + + + s00_axi_aresetn + + + + + + + RST + + + s00_axi_aresetn + + + + + + POLARITY + ACTIVE_LOW + + + + + m00_axi_aclk + + + + + + + CLK + + + m00_axi_aclk + + + + + + ASSOCIATED_BUSIF + m00_axi + + + ASSOCIATED_RESET + m00_axi_aresetn + + + + + s00_axi_aclk + + + + + + + CLK + + + s00_axi_aclk + + + + + + ASSOCIATED_BUSIF + s00_axi + + + ASSOCIATED_RESET + s00_axi_aresetn + + + + + led_clk + + + + + + + CLK + + + led_clk + + + + + + + + m00_axi + 4294967296 + 32 + + + + + s00_axi + + reg0 + 0 + 32 + 32 + register + + + + + + + xilinx_anylanguagesynthesis + Synthesis + :vivado.xilinx.com:synthesis + Verilog + ledmatrix_v1_0 + + xilinx_anylanguagesynthesis_view_fileset + + + + viewChecksum + 8d842412 + + + + + xilinx_anylanguagebehavioralsimulation + Simulation + :vivado.xilinx.com:simulation + Verilog + ledmatrix_v1_0 + + xilinx_anylanguagebehavioralsimulation_view_fileset + + + + viewChecksum + 8d842412 + + + + + xilinx_xpgui + UI Layout + :vivado.xilinx.com:xgui.ui + + xilinx_xpgui_view_fileset + + + + viewChecksum + 4635262c + + + + + + + led_r0 + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + led_r1 + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + led_g0 + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + led_g1 + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + led_b0 + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + led_b1 + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + led_bank + + out + + 3 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + led_clk + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + led_stb + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + led_oe + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + sys_rst + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_aclk + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_aresetn + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_awaddr + + in + + 4 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + s00_axi_awprot + + in + + 2 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + s00_axi_awvalid + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + s00_axi_awready + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_wdata + + in + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + s00_axi_wstrb + + in + + 3 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_wvalid + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + s00_axi_wready + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_bresp + + out + + 1 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_bvalid + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_bready + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + s00_axi_araddr + + in + + 4 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + s00_axi_arprot + + in + + 2 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + s00_axi_arvalid + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + s00_axi_arready + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_rdata + + out + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_rresp + + out + + 1 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_rvalid + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + s00_axi_rready + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_init_axi_txn + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_txn_done + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_error + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_aclk + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_aresetn + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awid + + out + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awaddr + + out + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awlen + + out + + 7 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awsize + + out + + 2 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awburst + + out + + 1 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awlock + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awcache + + out + + 3 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awprot + + out + + 2 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awqos + + out + + 3 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awuser + + out + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awvalid + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_awready + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_wdata + + out + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_wstrb + + out + + 3 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_wlast + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_wuser + + out + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_wvalid + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_wready + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_bid + + in + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_bresp + + in + + 1 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_buser + + in + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_bvalid + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_bready + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_arid + + out + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_araddr + + out + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_arlen + + out + + 7 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_arsize + + out + + 2 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_arburst + + out + + 1 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_arlock + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_arcache + + out + + 3 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_arprot + + out + + 2 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_arqos + + out + + 3 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_aruser + + out + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_arvalid + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + m00_axi_arready + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_rid + + in + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_rdata + + in + + 31 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_rresp + + in + + 1 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_rlast + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_ruser + + in + + 0 + 0 + + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_rvalid + + in + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + 0 + + + + + m00_axi_rready + + out + + + wire + xilinx_anylanguagesynthesis + xilinx_anylanguagebehavioralsimulation + + + + + + + + C_S00_AXI_DATA_WIDTH + C S00 Axi Data Width + 32 + + + C_S00_AXI_ADDR_WIDTH + C S00 Axi Addr Width + 5 + + + C_M00_AXI_TARGET_SLAVE_BASE_ADDR + C M00 Axi Target Slave Base Addr + 0x40000000 + + + C_M00_AXI_BURST_LEN + C M00 Axi Burst Len + 16 + + + C_M00_AXI_ID_WIDTH + C M00 Axi Id Width + 1 + + + C_M00_AXI_ADDR_WIDTH + C M00 Axi Addr Width + 32 + + + C_M00_AXI_DATA_WIDTH + C M00 Axi Data Width + 32 + + + C_M00_AXI_AWUSER_WIDTH + C M00 Axi Awuser Width + 0 + + + C_M00_AXI_ARUSER_WIDTH + C M00 Axi Aruser Width + 0 + + + C_M00_AXI_WUSER_WIDTH + C M00 Axi Wuser Width + 0 + + + C_M00_AXI_RUSER_WIDTH + C M00 Axi Ruser Width + 0 + + + C_M00_AXI_BUSER_WIDTH + C M00 Axi Buser Width + 0 + + + + + + choice_list_9d8b0d81 + ACTIVE_HIGH + ACTIVE_LOW + + + + + xilinx_anylanguagesynthesis_view_fileset + + hdl/ledmatrix_v1_0_S00_AXI.v + verilogSource + + + hdl/ledmatrix_v1_0_M00_AXI.v + verilogSource + + + src/blitter.v + verilogSource + + + hdl/ledmatrix_v1_0.v + verilogSource + CHECKSUM_a4469612 + + + + xilinx_anylanguagebehavioralsimulation_view_fileset + + hdl/ledmatrix_v1_0_S00_AXI.v + verilogSource + USED_IN_ipstatic + + + hdl/ledmatrix_v1_0_M00_AXI.v + verilogSource + USED_IN_ipstatic + + + src/blitter.v + verilogSource + USED_IN_ipstatic + + + hdl/ledmatrix_v1_0.v + verilogSource + USED_IN_ipstatic + + + + xilinx_xpgui_view_fileset + + xgui/ledmatrix_v1_0_v1_0.tcl + tclSource + CHECKSUM_4635262c + XGUI_VERSION_2 + + + + ledmatrix_v1_0_v1_0 + + + C_S00_AXI_DATA_WIDTH + C S00 Axi Data Width + 32 + + + C_S00_AXI_ADDR_WIDTH + C S00 Axi Addr Width + 5 + + + C_M00_AXI_TARGET_SLAVE_BASE_ADDR + C M00 Axi Target Slave Base Addr + 0x40000000 + + + C_M00_AXI_BURST_LEN + C M00 Axi Burst Len + 16 + + + C_M00_AXI_ID_WIDTH + C M00 Axi Id Width + 1 + + + C_M00_AXI_ADDR_WIDTH + C M00 Axi Addr Width + 32 + + + C_M00_AXI_DATA_WIDTH + C M00 Axi Data Width + 32 + + + C_M00_AXI_AWUSER_WIDTH + C M00 Axi Awuser Width + 0 + + + C_M00_AXI_ARUSER_WIDTH + C M00 Axi Aruser Width + 0 + + + C_M00_AXI_WUSER_WIDTH + C M00 Axi Wuser Width + 0 + + + C_M00_AXI_RUSER_WIDTH + C M00 Axi Ruser Width + 0 + + + C_M00_AXI_BUSER_WIDTH + C M00 Axi Buser Width + 0 + + + Component_Name + ledmatrix_v1_0_v1_0 + + + + + + zynq + + + /UserIP + + ledmatrix_v1_0_v1_0 + 12 + 2015-11-18T08:12:28Z + + /home/q3k/ip_repo/ledmatrix_1.0 + + + + 2015.3 + + + + + + + + + + diff --git a/hdl/ledmatrix_v1_0.v b/hdl/ledmatrix_v1_0.v new file mode 100644 index 0000000..975f7a4 --- /dev/null +++ b/hdl/ledmatrix_v1_0.v @@ -0,0 +1,235 @@ + +`timescale 1 ns / 1 ps + + module ledmatrix_v1_0 # + ( + // Users to add parameters here + + // User parameters ends + // Do not modify the parameters beyond this line + + + // Parameters of Axi Slave Bus Interface S00_AXI + parameter integer C_S00_AXI_DATA_WIDTH = 32, + parameter integer C_S00_AXI_ADDR_WIDTH = 5, + + // Parameters of Axi Master Bus Interface M00_AXI + parameter C_M00_AXI_TARGET_SLAVE_BASE_ADDR = 32'h40000000, + parameter integer C_M00_AXI_BURST_LEN = 16, + parameter integer C_M00_AXI_ID_WIDTH = 1, + parameter integer C_M00_AXI_ADDR_WIDTH = 32, + parameter integer C_M00_AXI_DATA_WIDTH = 32, + parameter integer C_M00_AXI_AWUSER_WIDTH = 0, + parameter integer C_M00_AXI_ARUSER_WIDTH = 0, + parameter integer C_M00_AXI_WUSER_WIDTH = 0, + parameter integer C_M00_AXI_RUSER_WIDTH = 0, + parameter integer C_M00_AXI_BUSER_WIDTH = 0 + ) + ( + // Users to add ports here + output wire /*[3:0]*/ led_r0, + output wire /*[3:0]*/ led_r1, + output wire /*[3:0]*/ led_g0, + output wire /*[3:0]*/ led_g1, + output wire /*[3:0]*/ led_b0, + output wire /*[3:0]*/ led_b1, + + output wire [3:0] led_bank, + output wire led_clk, + output wire led_stb, + output wire led_oe, + + input wire sys_rst, + // User ports ends + // Do not modify the ports beyond this line + + + // Ports of Axi Slave Bus Interface S00_AXI + input wire s00_axi_aclk, + input wire s00_axi_aresetn, + input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_awaddr, + input wire [2 : 0] s00_axi_awprot, + input wire s00_axi_awvalid, + output wire s00_axi_awready, + input wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_wdata, + input wire [(C_S00_AXI_DATA_WIDTH/8)-1 : 0] s00_axi_wstrb, + input wire s00_axi_wvalid, + output wire s00_axi_wready, + output wire [1 : 0] s00_axi_bresp, + output wire s00_axi_bvalid, + input wire s00_axi_bready, + input wire [C_S00_AXI_ADDR_WIDTH-1 : 0] s00_axi_araddr, + input wire [2 : 0] s00_axi_arprot, + input wire s00_axi_arvalid, + output wire s00_axi_arready, + output wire [C_S00_AXI_DATA_WIDTH-1 : 0] s00_axi_rdata, + output wire [1 : 0] s00_axi_rresp, + output wire s00_axi_rvalid, + input wire s00_axi_rready, + + // Ports of Axi Master Bus Interface M00_AXI + input wire m00_axi_init_axi_txn, + output wire m00_axi_txn_done, + output wire m00_axi_error, + input wire m00_axi_aclk, + input wire m00_axi_aresetn, + output wire [C_M00_AXI_ID_WIDTH-1 : 0] m00_axi_awid, + output wire [C_M00_AXI_ADDR_WIDTH-1 : 0] m00_axi_awaddr, + output wire [7 : 0] m00_axi_awlen, + output wire [2 : 0] m00_axi_awsize, + output wire [1 : 0] m00_axi_awburst, + output wire m00_axi_awlock, + output wire [3 : 0] m00_axi_awcache, + output wire [2 : 0] m00_axi_awprot, + output wire [3 : 0] m00_axi_awqos, + output wire [C_M00_AXI_AWUSER_WIDTH-1 : 0] m00_axi_awuser, + output wire m00_axi_awvalid, + input wire m00_axi_awready, + output wire [C_M00_AXI_DATA_WIDTH-1 : 0] m00_axi_wdata, + output wire [C_M00_AXI_DATA_WIDTH/8-1 : 0] m00_axi_wstrb, + output wire m00_axi_wlast, + output wire [C_M00_AXI_WUSER_WIDTH-1 : 0] m00_axi_wuser, + output wire m00_axi_wvalid, + input wire m00_axi_wready, + input wire [C_M00_AXI_ID_WIDTH-1 : 0] m00_axi_bid, + input wire [1 : 0] m00_axi_bresp, + input wire [C_M00_AXI_BUSER_WIDTH-1 : 0] m00_axi_buser, + input wire m00_axi_bvalid, + output wire m00_axi_bready, + output wire [C_M00_AXI_ID_WIDTH-1 : 0] m00_axi_arid, + output wire [C_M00_AXI_ADDR_WIDTH-1 : 0] m00_axi_araddr, + output wire [7 : 0] m00_axi_arlen, + output wire [2 : 0] m00_axi_arsize, + output wire [1 : 0] m00_axi_arburst, + output wire m00_axi_arlock, + output wire [3 : 0] m00_axi_arcache, + output wire [2 : 0] m00_axi_arprot, + output wire [3 : 0] m00_axi_arqos, + output wire [C_M00_AXI_ARUSER_WIDTH-1 : 0] m00_axi_aruser, + output wire m00_axi_arvalid, + input wire m00_axi_arready, + input wire [C_M00_AXI_ID_WIDTH-1 : 0] m00_axi_rid, + input wire [C_M00_AXI_DATA_WIDTH-1 : 0] m00_axi_rdata, + input wire [1 : 0] m00_axi_rresp, + input wire m00_axi_rlast, + input wire [C_M00_AXI_RUSER_WIDTH-1 : 0] m00_axi_ruser, + input wire m00_axi_rvalid, + output wire m00_axi_rready + ); +// Instantiation of Axi Bus Interface S00_AXI + ledmatrix_v1_0_S00_AXI # ( + .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH), + .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH) + ) ledmatrix_v1_0_S00_AXI_inst ( + .S_AXI_ACLK(s00_axi_aclk), + .S_AXI_ARESETN(s00_axi_aresetn), + .S_AXI_AWADDR(s00_axi_awaddr), + .S_AXI_AWPROT(s00_axi_awprot), + .S_AXI_AWVALID(s00_axi_awvalid), + .S_AXI_AWREADY(s00_axi_awready), + .S_AXI_WDATA(s00_axi_wdata), + .S_AXI_WSTRB(s00_axi_wstrb), + .S_AXI_WVALID(s00_axi_wvalid), + .S_AXI_WREADY(s00_axi_wready), + .S_AXI_BRESP(s00_axi_bresp), + .S_AXI_BVALID(s00_axi_bvalid), + .S_AXI_BREADY(s00_axi_bready), + .S_AXI_ARADDR(s00_axi_araddr), + .S_AXI_ARPROT(s00_axi_arprot), + .S_AXI_ARVALID(s00_axi_arvalid), + .S_AXI_ARREADY(s00_axi_arready), + .S_AXI_RDATA(s00_axi_rdata), + .S_AXI_RRESP(s00_axi_rresp), + .S_AXI_RVALID(s00_axi_rvalid), + .S_AXI_RREADY(s00_axi_rready) + ); + +// Instantiation of Axi Bus Interface M00_AXI + ledmatrix_v1_0_M00_AXI # ( + .C_M_TARGET_SLAVE_BASE_ADDR(C_M00_AXI_TARGET_SLAVE_BASE_ADDR), + .C_M_AXI_BURST_LEN(C_M00_AXI_BURST_LEN), + .C_M_AXI_ID_WIDTH(C_M00_AXI_ID_WIDTH), + .C_M_AXI_ADDR_WIDTH(C_M00_AXI_ADDR_WIDTH), + .C_M_AXI_DATA_WIDTH(C_M00_AXI_DATA_WIDTH), + .C_M_AXI_AWUSER_WIDTH(C_M00_AXI_AWUSER_WIDTH), + .C_M_AXI_ARUSER_WIDTH(C_M00_AXI_ARUSER_WIDTH), + .C_M_AXI_WUSER_WIDTH(C_M00_AXI_WUSER_WIDTH), + .C_M_AXI_RUSER_WIDTH(C_M00_AXI_RUSER_WIDTH), + .C_M_AXI_BUSER_WIDTH(C_M00_AXI_BUSER_WIDTH) + ) ledmatrix_v1_0_M00_AXI_inst ( + .INIT_AXI_TXN(m00_axi_init_axi_txn), + .TXN_DONE(m00_axi_txn_done), + .ERROR(m00_axi_error), + .M_AXI_ACLK(m00_axi_aclk), + .M_AXI_ARESETN(m00_axi_aresetn), + .M_AXI_AWID(m00_axi_awid), + .M_AXI_AWADDR(m00_axi_awaddr), + .M_AXI_AWLEN(m00_axi_awlen), + .M_AXI_AWSIZE(m00_axi_awsize), + .M_AXI_AWBURST(m00_axi_awburst), + .M_AXI_AWLOCK(m00_axi_awlock), + .M_AXI_AWCACHE(m00_axi_awcache), + .M_AXI_AWPROT(m00_axi_awprot), + .M_AXI_AWQOS(m00_axi_awqos), + .M_AXI_AWUSER(m00_axi_awuser), + .M_AXI_AWVALID(m00_axi_awvalid), + .M_AXI_AWREADY(m00_axi_awready), + .M_AXI_WDATA(m00_axi_wdata), + .M_AXI_WSTRB(m00_axi_wstrb), + .M_AXI_WLAST(m00_axi_wlast), + .M_AXI_WUSER(m00_axi_wuser), + .M_AXI_WVALID(m00_axi_wvalid), + .M_AXI_WREADY(m00_axi_wready), + .M_AXI_BID(m00_axi_bid), + .M_AXI_BRESP(m00_axi_bresp), + .M_AXI_BUSER(m00_axi_buser), + .M_AXI_BVALID(m00_axi_bvalid), + .M_AXI_BREADY(m00_axi_bready), + .M_AXI_ARID(m00_axi_arid), + .M_AXI_ARADDR(m00_axi_araddr), + .M_AXI_ARLEN(m00_axi_arlen), + .M_AXI_ARSIZE(m00_axi_arsize), + .M_AXI_ARBURST(m00_axi_arburst), + .M_AXI_ARLOCK(m00_axi_arlock), + .M_AXI_ARCACHE(m00_axi_arcache), + .M_AXI_ARPROT(m00_axi_arprot), + .M_AXI_ARQOS(m00_axi_arqos), + .M_AXI_ARUSER(m00_axi_aruser), + .M_AXI_ARVALID(m00_axi_arvalid), + .M_AXI_ARREADY(m00_axi_arready), + .M_AXI_RID(m00_axi_rid), + .M_AXI_RDATA(m00_axi_rdata), + .M_AXI_RRESP(m00_axi_rresp), + .M_AXI_RLAST(m00_axi_rlast), + .M_AXI_RUSER(m00_axi_ruser), + .M_AXI_RVALID(m00_axi_rvalid), + .M_AXI_RREADY(m00_axi_rready) + ); + + // Add user logic here + wire sys_en = 1; + reg [9:0] foo = 1; + always @(posedge s00_axi_aclk) begin + foo <= foo + 1; + end + blitter # ( + ) blt ( + .sys_en(sys_en), + .sys_clk(foo[2]), + .sys_rst(sys_rst), + + .led_clk(led_clk), + .led_stb(led_stb), + .led_oe(led_oe), + + .led_bank(led_bank) + ); + + assign led_r0 = 1; + assign led_r1 = 0; + assign led_g0 = 0; + assign led_g1 = 1; + assign led_b0 = 0; + assign led_b1 = 0; + // User logic ends + endmodule diff --git a/hdl/ledmatrix_v1_0_M00_AXI.v b/hdl/ledmatrix_v1_0_M00_AXI.v new file mode 100644 index 0000000..6202f32 --- /dev/null +++ b/hdl/ledmatrix_v1_0_M00_AXI.v @@ -0,0 +1,907 @@ + +`timescale 1 ns / 1 ps + + module ledmatrix_v1_0_M00_AXI # + ( + // Users to add parameters here + + // User parameters ends + // Do not modify the parameters beyond this line + + // Base address of targeted slave + parameter C_M_TARGET_SLAVE_BASE_ADDR = 32'h40000000, + // Burst Length. Supports 1, 2, 4, 8, 16, 32, 64, 128, 256 burst lengths + parameter integer C_M_AXI_BURST_LEN = 16, + // Thread ID Width + parameter integer C_M_AXI_ID_WIDTH = 1, + // Width of Address Bus + parameter integer C_M_AXI_ADDR_WIDTH = 32, + // Width of Data Bus + parameter integer C_M_AXI_DATA_WIDTH = 32, + // Width of User Write Address Bus + parameter integer C_M_AXI_AWUSER_WIDTH = 0, + // Width of User Read Address Bus + parameter integer C_M_AXI_ARUSER_WIDTH = 0, + // Width of User Write Data Bus + parameter integer C_M_AXI_WUSER_WIDTH = 0, + // Width of User Read Data Bus + parameter integer C_M_AXI_RUSER_WIDTH = 0, + // Width of User Response Bus + parameter integer C_M_AXI_BUSER_WIDTH = 0 + ) + ( + // Users to add ports here + + // User ports ends + // Do not modify the ports beyond this line + + // Initiate AXI transactions + input wire INIT_AXI_TXN, + // Asserts when transaction is complete + output wire TXN_DONE, + // Asserts when ERROR is detected + output reg ERROR, + // Global Clock Signal. + input wire M_AXI_ACLK, + // Global Reset Singal. This Signal is Active Low + input wire M_AXI_ARESETN, + // Master Interface Write Address ID + output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_AWID, + // Master Interface Write Address + output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_AWADDR, + // Burst length. The burst length gives the exact number of transfers in a burst + output wire [7 : 0] M_AXI_AWLEN, + // Burst size. This signal indicates the size of each transfer in the burst + output wire [2 : 0] M_AXI_AWSIZE, + // Burst type. The burst type and the size information, + // determine how the address for each transfer within the burst is calculated. + output wire [1 : 0] M_AXI_AWBURST, + // Lock type. Provides additional information about the + // atomic characteristics of the transfer. + output wire M_AXI_AWLOCK, + // Memory type. This signal indicates how transactions + // are required to progress through a system. + output wire [3 : 0] M_AXI_AWCACHE, + // Protection type. This signal indicates the privilege + // and security level of the transaction, and whether + // the transaction is a data access or an instruction access. + output wire [2 : 0] M_AXI_AWPROT, + // Quality of Service, QoS identifier sent for each write transaction. + output wire [3 : 0] M_AXI_AWQOS, + // Optional User-defined signal in the write address channel. + output wire [C_M_AXI_AWUSER_WIDTH-1 : 0] M_AXI_AWUSER, + // Write address valid. This signal indicates that + // the channel is signaling valid write address and control information. + output wire M_AXI_AWVALID, + // Write address ready. This signal indicates that + // the slave is ready to accept an address and associated control signals + input wire M_AXI_AWREADY, + // Master Interface Write Data. + output wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_WDATA, + // Write strobes. This signal indicates which byte + // lanes hold valid data. There is one write strobe + // bit for each eight bits of the write data bus. + output wire [C_M_AXI_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB, + // Write last. This signal indicates the last transfer in a write burst. + output wire M_AXI_WLAST, + // Optional User-defined signal in the write data channel. + output wire [C_M_AXI_WUSER_WIDTH-1 : 0] M_AXI_WUSER, + // Write valid. This signal indicates that valid write + // data and strobes are available + output wire M_AXI_WVALID, + // Write ready. This signal indicates that the slave + // can accept the write data. + input wire M_AXI_WREADY, + // Master Interface Write Response. + input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_BID, + // Write response. This signal indicates the status of the write transaction. + input wire [1 : 0] M_AXI_BRESP, + // Optional User-defined signal in the write response channel + input wire [C_M_AXI_BUSER_WIDTH-1 : 0] M_AXI_BUSER, + // Write response valid. This signal indicates that the + // channel is signaling a valid write response. + input wire M_AXI_BVALID, + // Response ready. This signal indicates that the master + // can accept a write response. + output wire M_AXI_BREADY, + // Master Interface Read Address. + output wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_ARID, + // Read address. This signal indicates the initial + // address of a read burst transaction. + output wire [C_M_AXI_ADDR_WIDTH-1 : 0] M_AXI_ARADDR, + // Burst length. The burst length gives the exact number of transfers in a burst + output wire [7 : 0] M_AXI_ARLEN, + // Burst size. This signal indicates the size of each transfer in the burst + output wire [2 : 0] M_AXI_ARSIZE, + // Burst type. The burst type and the size information, + // determine how the address for each transfer within the burst is calculated. + output wire [1 : 0] M_AXI_ARBURST, + // Lock type. Provides additional information about the + // atomic characteristics of the transfer. + output wire M_AXI_ARLOCK, + // Memory type. This signal indicates how transactions + // are required to progress through a system. + output wire [3 : 0] M_AXI_ARCACHE, + // Protection type. This signal indicates the privilege + // and security level of the transaction, and whether + // the transaction is a data access or an instruction access. + output wire [2 : 0] M_AXI_ARPROT, + // Quality of Service, QoS identifier sent for each read transaction + output wire [3 : 0] M_AXI_ARQOS, + // Optional User-defined signal in the read address channel. + output wire [C_M_AXI_ARUSER_WIDTH-1 : 0] M_AXI_ARUSER, + // Write address valid. This signal indicates that + // the channel is signaling valid read address and control information + output wire M_AXI_ARVALID, + // Read address ready. This signal indicates that + // the slave is ready to accept an address and associated control signals + input wire M_AXI_ARREADY, + // Read ID tag. This signal is the identification tag + // for the read data group of signals generated by the slave. + input wire [C_M_AXI_ID_WIDTH-1 : 0] M_AXI_RID, + // Master Read Data + input wire [C_M_AXI_DATA_WIDTH-1 : 0] M_AXI_RDATA, + // Read response. This signal indicates the status of the read transfer + input wire [1 : 0] M_AXI_RRESP, + // Read last. This signal indicates the last transfer in a read burst + input wire M_AXI_RLAST, + // Optional User-defined signal in the read address channel. + input wire [C_M_AXI_RUSER_WIDTH-1 : 0] M_AXI_RUSER, + // Read valid. This signal indicates that the channel + // is signaling the required read data. + input wire M_AXI_RVALID, + // Read ready. This signal indicates that the master can + // accept the read data and response information. + output wire M_AXI_RREADY + ); + + + // function called clogb2 that returns an integer which has the + //value of the ceiling of the log base 2 + + // function called clogb2 that returns an integer which has the + // value of the ceiling of the log base 2. + function integer clogb2 (input integer bit_depth); + begin + for(clogb2=0; bit_depth>0; clogb2=clogb2+1) + bit_depth = bit_depth >> 1; + end + endfunction + + // C_TRANSACTIONS_NUM is the width of the index counter for + // number of write or read transaction. + localparam integer C_TRANSACTIONS_NUM = clogb2(C_M_AXI_BURST_LEN-1); + + // Burst length for transactions, in C_M_AXI_DATA_WIDTHs. + // Non-2^n lengths will eventually cause bursts across 4K address boundaries. + localparam integer C_MASTER_LENGTH = 12; + // total number of burst transfers is master length divided by burst length and burst size + localparam integer C_NO_BURSTS_REQ = C_MASTER_LENGTH-clogb2((C_M_AXI_BURST_LEN*C_M_AXI_DATA_WIDTH/8)-1); + // Example State machine to initialize counter, initialize write transactions, + // initialize read transactions and comparison of read data with the + // written data words. + parameter [1:0] IDLE = 2'b00, // This state initiates AXI4Lite transaction + // after the state machine changes state to INIT_WRITE + // when there is 0 to 1 transition on INIT_AXI_TXN + INIT_WRITE = 2'b01, // This state initializes write transaction, + // once writes are done, the state machine + // changes state to INIT_READ + INIT_READ = 2'b10, // This state initializes read transaction + // once reads are done, the state machine + // changes state to INIT_COMPARE + INIT_COMPARE = 2'b11; // This state issues the status of comparison + // of the written data with the read data + + reg [1:0] mst_exec_state; + + // AXI4LITE signals + //AXI4 internal temp signals + reg [C_M_AXI_ADDR_WIDTH-1 : 0] axi_awaddr; + reg axi_awvalid; + reg [C_M_AXI_DATA_WIDTH-1 : 0] axi_wdata; + reg axi_wlast; + reg axi_wvalid; + reg axi_bready; + reg [C_M_AXI_ADDR_WIDTH-1 : 0] axi_araddr; + reg axi_arvalid; + reg axi_rready; + //write beat count in a burst + reg [C_TRANSACTIONS_NUM : 0] write_index; + //read beat count in a burst + reg [C_TRANSACTIONS_NUM : 0] read_index; + //size of C_M_AXI_BURST_LEN length burst in bytes + wire [C_TRANSACTIONS_NUM+2 : 0] burst_size_bytes; + //The burst counters are used to track the number of burst transfers of C_M_AXI_BURST_LEN burst length needed to transfer 2^C_MASTER_LENGTH bytes of data. + reg [C_NO_BURSTS_REQ : 0] write_burst_counter; + reg [C_NO_BURSTS_REQ : 0] read_burst_counter; + reg start_single_burst_write; + reg start_single_burst_read; + reg writes_done; + reg reads_done; + reg error_reg; + reg compare_done; + reg read_mismatch; + reg burst_write_active; + reg burst_read_active; + reg [C_M_AXI_DATA_WIDTH-1 : 0] expected_rdata; + //Interface response error flags + wire write_resp_error; + wire read_resp_error; + wire wnext; + wire rnext; + reg init_txn_ff; + reg init_txn_ff2; + reg init_txn_edge; + wire init_txn_pulse; + + + // I/O Connections assignments + + //I/O Connections. Write Address (AW) + assign M_AXI_AWID = 'b0; + //The AXI address is a concatenation of the target base address + active offset range + assign M_AXI_AWADDR = C_M_TARGET_SLAVE_BASE_ADDR + axi_awaddr; + //Burst LENgth is number of transaction beats, minus 1 + assign M_AXI_AWLEN = C_M_AXI_BURST_LEN - 1; + //Size should be C_M_AXI_DATA_WIDTH, in 2^SIZE bytes, otherwise narrow bursts are used + assign M_AXI_AWSIZE = clogb2((C_M_AXI_DATA_WIDTH/8)-1); + //INCR burst type is usually used, except for keyhole bursts + assign M_AXI_AWBURST = 2'b01; + assign M_AXI_AWLOCK = 1'b0; + //Update value to 4'b0011 if coherent accesses to be used via the Zynq ACP port. Not Allocated, Modifiable, not Bufferable. Not Bufferable since this example is meant to test memory, not intermediate cache. + assign M_AXI_AWCACHE = 4'b0010; + assign M_AXI_AWPROT = 3'h0; + assign M_AXI_AWQOS = 4'h0; + assign M_AXI_AWUSER = 'b1; + assign M_AXI_AWVALID = axi_awvalid; + //Write Data(W) + assign M_AXI_WDATA = axi_wdata; + //All bursts are complete and aligned in this example + assign M_AXI_WSTRB = {(C_M_AXI_DATA_WIDTH/8){1'b1}}; + assign M_AXI_WLAST = axi_wlast; + assign M_AXI_WUSER = 'b0; + assign M_AXI_WVALID = axi_wvalid; + //Write Response (B) + assign M_AXI_BREADY = axi_bready; + //Read Address (AR) + assign M_AXI_ARID = 'b0; + assign M_AXI_ARADDR = C_M_TARGET_SLAVE_BASE_ADDR + axi_araddr; + //Burst LENgth is number of transaction beats, minus 1 + assign M_AXI_ARLEN = C_M_AXI_BURST_LEN - 1; + //Size should be C_M_AXI_DATA_WIDTH, in 2^n bytes, otherwise narrow bursts are used + assign M_AXI_ARSIZE = clogb2((C_M_AXI_DATA_WIDTH/8)-1); + //INCR burst type is usually used, except for keyhole bursts + assign M_AXI_ARBURST = 2'b01; + assign M_AXI_ARLOCK = 1'b0; + //Update value to 4'b0011 if coherent accesses to be used via the Zynq ACP port. Not Allocated, Modifiable, not Bufferable. Not Bufferable since this example is meant to test memory, not intermediate cache. + assign M_AXI_ARCACHE = 4'b0010; + assign M_AXI_ARPROT = 3'h0; + assign M_AXI_ARQOS = 4'h0; + assign M_AXI_ARUSER = 'b1; + assign M_AXI_ARVALID = axi_arvalid; + //Read and Read Response (R) + assign M_AXI_RREADY = axi_rready; + //Example design I/O + assign TXN_DONE = compare_done; + //Burst size in bytes + assign burst_size_bytes = C_M_AXI_BURST_LEN * C_M_AXI_DATA_WIDTH/8; + assign init_txn_pulse = (!init_txn_ff2) && init_txn_ff; + + + //Generate a pulse to initiate AXI transaction. + always @(posedge M_AXI_ACLK) + begin + // Initiates AXI transaction delay + if (M_AXI_ARESETN == 0 ) + begin + init_txn_ff <= 1'b0; + init_txn_ff2 <= 1'b0; + end + else + begin + init_txn_ff <= INIT_AXI_TXN; + init_txn_ff2 <= init_txn_ff; + end + end + + + //-------------------- + //Write Address Channel + //-------------------- + + // The purpose of the write address channel is to request the address and + // command information for the entire transaction. It is a single beat + // of information. + + // The AXI4 Write address channel in this example will continue to initiate + // write commands as fast as it is allowed by the slave/interconnect. + // The address will be incremented on each accepted address transaction, + // by burst_size_byte to point to the next address. + + always @(posedge M_AXI_ACLK) + begin + + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) + begin + axi_awvalid <= 1'b0; + end + // If previously not valid , start next transaction + else if (~axi_awvalid && start_single_burst_write) + begin + axi_awvalid <= 1'b1; + end + /* Once asserted, VALIDs cannot be deasserted, so axi_awvalid + must wait until transaction is accepted */ + else if (M_AXI_AWREADY && axi_awvalid) + begin + axi_awvalid <= 1'b0; + end + else + axi_awvalid <= axi_awvalid; + end + + + // Next address after AWREADY indicates previous address acceptance + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) + begin + axi_awaddr <= 'b0; + end + else if (M_AXI_AWREADY && axi_awvalid) + begin + axi_awaddr <= axi_awaddr + burst_size_bytes; + end + else + axi_awaddr <= axi_awaddr; + end + + + //-------------------- + //Write Data Channel + //-------------------- + + //The write data will continually try to push write data across the interface. + + //The amount of data accepted will depend on the AXI slave and the AXI + //Interconnect settings, such as if there are FIFOs enabled in interconnect. + + //Note that there is no explicit timing relationship to the write address channel. + //The write channel has its own throttling flag, separate from the AW channel. + + //Synchronization between the channels must be determined by the user. + + //The simpliest but lowest performance would be to only issue one address write + //and write data burst at a time. + + //In this example they are kept in sync by using the same address increment + //and burst sizes. Then the AW and W channels have their transactions measured + //with threshold counters as part of the user logic, to make sure neither + //channel gets too far ahead of each other. + + //Forward movement occurs when the write channel is valid and ready + + assign wnext = M_AXI_WREADY & axi_wvalid; + + // WVALID logic, similar to the axi_awvalid always block above + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) + begin + axi_wvalid <= 1'b0; + end + // If previously not valid, start next transaction + else if (~axi_wvalid && start_single_burst_write) + begin + axi_wvalid <= 1'b1; + end + /* If WREADY and too many writes, throttle WVALID + Once asserted, VALIDs cannot be deasserted, so WVALID + must wait until burst is complete with WLAST */ + else if (wnext && axi_wlast) + axi_wvalid <= 1'b0; + else + axi_wvalid <= axi_wvalid; + end + + + //WLAST generation on the MSB of a counter underflow + // WVALID logic, similar to the axi_awvalid always block above + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) + begin + axi_wlast <= 1'b0; + end + // axi_wlast is asserted when the write index + // count reaches the penultimate count to synchronize + // with the last write data when write_index is b1111 + // else if (&(write_index[C_TRANSACTIONS_NUM-1:1])&& ~write_index[0] && wnext) + else if (((write_index == C_M_AXI_BURST_LEN-2 && C_M_AXI_BURST_LEN >= 2) && wnext) || (C_M_AXI_BURST_LEN == 1 )) + begin + axi_wlast <= 1'b1; + end + // Deassrt axi_wlast when the last write data has been + // accepted by the slave with a valid response + else if (wnext) + axi_wlast <= 1'b0; + else if (axi_wlast && C_M_AXI_BURST_LEN == 1) + axi_wlast <= 1'b0; + else + axi_wlast <= axi_wlast; + end + + + /* Burst length counter. Uses extra counter register bit to indicate terminal + count to reduce decode logic */ + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 || start_single_burst_write == 1'b1) + begin + write_index <= 0; + end + else if (wnext && (write_index != C_M_AXI_BURST_LEN-1)) + begin + write_index <= write_index + 1; + end + else + write_index <= write_index; + end + + + /* Write Data Generator + Data pattern is only a simple incrementing count from 0 for each burst */ + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) + axi_wdata <= 'b1; + //else if (wnext && axi_wlast) + // axi_wdata <= 'b0; + else if (wnext) + axi_wdata <= axi_wdata + 1; + else + axi_wdata <= axi_wdata; + end + + + //---------------------------- + //Write Response (B) Channel + //---------------------------- + + //The write response channel provides feedback that the write has committed + //to memory. BREADY will occur when all of the data and the write address + //has arrived and been accepted by the slave. + + //The write issuance (number of outstanding write addresses) is started by + //the Address Write transfer, and is completed by a BREADY/BRESP. + + //While negating BREADY will eventually throttle the AWREADY signal, + //it is best not to throttle the whole data channel this way. + + //The BRESP bit [1] is used indicate any errors from the interconnect or + //slave for the entire write burst. This example will capture the error + //into the ERROR output. + + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) + begin + axi_bready <= 1'b0; + end + // accept/acknowledge bresp with axi_bready by the master + // when M_AXI_BVALID is asserted by slave + else if (M_AXI_BVALID && ~axi_bready) + begin + axi_bready <= 1'b1; + end + // deassert after one clock cycle + else if (axi_bready) + begin + axi_bready <= 1'b0; + end + // retain the previous value + else + axi_bready <= axi_bready; + end + + + //Flag any write response errors + assign write_resp_error = axi_bready & M_AXI_BVALID & M_AXI_BRESP[1]; + + + //---------------------------- + //Read Address Channel + //---------------------------- + + //The Read Address Channel (AW) provides a similar function to the + //Write Address channel- to provide the tranfer qualifiers for the burst. + + //In this example, the read address increments in the same + //manner as the write address channel. + + always @(posedge M_AXI_ACLK) + begin + + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) + begin + axi_arvalid <= 1'b0; + end + // If previously not valid , start next transaction + else if (~axi_arvalid && start_single_burst_read) + begin + axi_arvalid <= 1'b1; + end + else if (M_AXI_ARREADY && axi_arvalid) + begin + axi_arvalid <= 1'b0; + end + else + axi_arvalid <= axi_arvalid; + end + + + // Next address after ARREADY indicates previous address acceptance + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) + begin + axi_araddr <= 'b0; + end + else if (M_AXI_ARREADY && axi_arvalid) + begin + axi_araddr <= axi_araddr + burst_size_bytes; + end + else + axi_araddr <= axi_araddr; + end + + + //-------------------------------- + //Read Data (and Response) Channel + //-------------------------------- + + // Forward movement occurs when the channel is valid and ready + assign rnext = M_AXI_RVALID && axi_rready; + + + // Burst length counter. Uses extra counter register bit to indicate + // terminal count to reduce decode logic + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 || start_single_burst_read) + begin + read_index <= 0; + end + else if (rnext && (read_index != C_M_AXI_BURST_LEN-1)) + begin + read_index <= read_index + 1; + end + else + read_index <= read_index; + end + + + /* + The Read Data channel returns the results of the read request + + In this example the data checker is always able to accept + more data, so no need to throttle the RREADY signal + */ + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) + begin + axi_rready <= 1'b0; + end + // accept/acknowledge rdata/rresp with axi_rready by the master + // when M_AXI_RVALID is asserted by slave + else if (M_AXI_RVALID) + begin + if (M_AXI_RLAST && axi_rready) + begin + axi_rready <= 1'b0; + end + else + begin + axi_rready <= 1'b1; + end + end + // retain the previous value + end + + //Check received read data against data generator + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) + begin + read_mismatch <= 1'b0; + end + //Only check data when RVALID is active + else if (rnext && (M_AXI_RDATA != expected_rdata)) + begin + read_mismatch <= 1'b1; + end + else + read_mismatch <= 1'b0; + end + + //Flag any read response errors + assign read_resp_error = axi_rready & M_AXI_RVALID & M_AXI_RRESP[1]; + + + //---------------------------------------- + //Example design read check data generator + //----------------------------------------- + + //Generate expected read data to check against actual read data + + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)// || M_AXI_RLAST) + expected_rdata <= 'b1; + else if (M_AXI_RVALID && axi_rready) + expected_rdata <= expected_rdata + 1; + else + expected_rdata <= expected_rdata; + end + + + //---------------------------------- + //Example design error register + //---------------------------------- + + //Register and hold any data mismatches, or read/write interface errors + + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) + begin + error_reg <= 1'b0; + end + else if (read_mismatch || write_resp_error || read_resp_error) + begin + error_reg <= 1'b1; + end + else + error_reg <= error_reg; + end + + + //-------------------------------- + //Example design throttling + //-------------------------------- + + // For maximum port throughput, this user example code will try to allow + // each channel to run as independently and as quickly as possible. + + // However, there are times when the flow of data needs to be throtted by + // the user application. This example application requires that data is + // not read before it is written and that the write channels do not + // advance beyond an arbitrary threshold (say to prevent an + // overrun of the current read address by the write address). + + // From AXI4 Specification, 13.13.1: "If a master requires ordering between + // read and write transactions, it must ensure that a response is received + // for the previous transaction before issuing the next transaction." + + // This example accomplishes this user application throttling through: + // -Reads wait for writes to fully complete + // -Address writes wait when not read + issued transaction counts pass + // a parameterized threshold + // -Writes wait when a not read + active data burst count pass + // a parameterized threshold + + // write_burst_counter counter keeps track with the number of burst transaction initiated + // against the number of burst transactions the master needs to initiate + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1 ) + begin + write_burst_counter <= 'b0; + end + else if (M_AXI_AWREADY && axi_awvalid) + begin + if (write_burst_counter[C_NO_BURSTS_REQ] == 1'b0) + begin + write_burst_counter <= write_burst_counter + 1'b1; + //write_burst_counter[C_NO_BURSTS_REQ] <= 1'b1; + end + end + else + write_burst_counter <= write_burst_counter; + end + + // read_burst_counter counter keeps track with the number of burst transaction initiated + // against the number of burst transactions the master needs to initiate + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) + begin + read_burst_counter <= 'b0; + end + else if (M_AXI_ARREADY && axi_arvalid) + begin + if (read_burst_counter[C_NO_BURSTS_REQ] == 1'b0) + begin + read_burst_counter <= read_burst_counter + 1'b1; + //read_burst_counter[C_NO_BURSTS_REQ] <= 1'b1; + end + end + else + read_burst_counter <= read_burst_counter; + end + + + //implement master command interface state machine + + always @ ( posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 1'b0 ) + begin + // reset condition + // All the signals are assigned default values under reset condition + mst_exec_state <= IDLE; + start_single_burst_write <= 1'b0; + start_single_burst_read <= 1'b0; + compare_done <= 1'b0; + ERROR <= 1'b0; + end + else + begin + + // state transition + case (mst_exec_state) + + IDLE: + // This state is responsible to wait for user defined C_M_START_COUNT + // number of clock cycles. + if ( init_txn_pulse == 1'b1) + begin + mst_exec_state <= INIT_WRITE; + ERROR <= 1'b0; + compare_done <= 1'b0; + end + else + begin + mst_exec_state <= IDLE; + end + + INIT_WRITE: + // This state is responsible to issue start_single_write pulse to + // initiate a write transaction. Write transactions will be + // issued until burst_write_active signal is asserted. + // write controller + if (writes_done) + begin + mst_exec_state <= INIT_READ;// + end + else + begin + mst_exec_state <= INIT_WRITE; + + if (~axi_awvalid && ~start_single_burst_write && ~burst_write_active) + begin + start_single_burst_write <= 1'b1; + end + else + begin + start_single_burst_write <= 1'b0; //Negate to generate a pulse + end + end + + INIT_READ: + // This state is responsible to issue start_single_read pulse to + // initiate a read transaction. Read transactions will be + // issued until burst_read_active signal is asserted. + // read controller + if (reads_done) + begin + mst_exec_state <= INIT_COMPARE; + end + else + begin + mst_exec_state <= INIT_READ; + + if (~axi_arvalid && ~burst_read_active && ~start_single_burst_read) + begin + start_single_burst_read <= 1'b1; + end + else + begin + start_single_burst_read <= 1'b0; //Negate to generate a pulse + end + end + + INIT_COMPARE: + // This state is responsible to issue the state of comparison + // of written data with the read data. If no error flags are set, + // compare_done signal will be asseted to indicate success. + //if (~error_reg) + begin + ERROR <= error_reg; + mst_exec_state <= IDLE; + compare_done <= 1'b1; + end + default : + begin + mst_exec_state <= IDLE; + end + endcase + end + end //MASTER_EXECUTION_PROC + + + // burst_write_active signal is asserted when there is a burst write transaction + // is initiated by the assertion of start_single_burst_write. burst_write_active + // signal remains asserted until the burst write is accepted by the slave + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) + burst_write_active <= 1'b0; + + //The burst_write_active is asserted when a write burst transaction is initiated + else if (start_single_burst_write) + burst_write_active <= 1'b1; + else if (M_AXI_BVALID && axi_bready) + burst_write_active <= 0; + end + + // Check for last write completion. + + // This logic is to qualify the last write count with the final write + // response. This demonstrates how to confirm that a write has been + // committed. + + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) + writes_done <= 1'b0; + + //The writes_done should be associated with a bready response + //else if (M_AXI_BVALID && axi_bready && (write_burst_counter == {(C_NO_BURSTS_REQ-1){1}}) && axi_wlast) + else if (M_AXI_BVALID && (write_burst_counter[C_NO_BURSTS_REQ]) && axi_bready) + writes_done <= 1'b1; + else + writes_done <= writes_done; + end + + // burst_read_active signal is asserted when there is a burst write transaction + // is initiated by the assertion of start_single_burst_write. start_single_burst_read + // signal remains asserted until the burst read is accepted by the master + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) + burst_read_active <= 1'b0; + + //The burst_write_active is asserted when a write burst transaction is initiated + else if (start_single_burst_read) + burst_read_active <= 1'b1; + else if (M_AXI_RVALID && axi_rready && M_AXI_RLAST) + burst_read_active <= 0; + end + + + // Check for last read completion. + + // This logic is to qualify the last read count with the final read + // response. This demonstrates how to confirm that a read has been + // committed. + + always @(posedge M_AXI_ACLK) + begin + if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1) + reads_done <= 1'b0; + + //The reads_done should be associated with a rready response + //else if (M_AXI_BVALID && axi_bready && (write_burst_counter == {(C_NO_BURSTS_REQ-1){1}}) && axi_wlast) + else if (M_AXI_RVALID && axi_rready && (read_index == C_M_AXI_BURST_LEN-1) && (read_burst_counter[C_NO_BURSTS_REQ])) + reads_done <= 1'b1; + else + reads_done <= reads_done; + end + + // Add user logic here + + // User logic ends + + endmodule diff --git a/hdl/ledmatrix_v1_0_S00_AXI.v b/hdl/ledmatrix_v1_0_S00_AXI.v new file mode 100644 index 0000000..297b94f --- /dev/null +++ b/hdl/ledmatrix_v1_0_S00_AXI.v @@ -0,0 +1,407 @@ + +`timescale 1 ns / 1 ps + + module ledmatrix_v1_0_S00_AXI # + ( + // Users to add parameters here + + // User parameters ends + // Do not modify the parameters beyond this line + + // Width of S_AXI data bus + parameter integer C_S_AXI_DATA_WIDTH = 32, + // Width of S_AXI address bus + parameter integer C_S_AXI_ADDR_WIDTH = 5 + ) + ( + // Users to add ports here + + // User ports ends + // Do not modify the ports beyond this line + + // Global Clock Signal + input wire S_AXI_ACLK, + // Global Reset Signal. This Signal is Active LOW + input wire S_AXI_ARESETN, + // Write address (issued by master, acceped by Slave) + input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR, + // Write channel Protection type. This signal indicates the + // privilege and security level of the transaction, and whether + // the transaction is a data access or an instruction access. + input wire [2 : 0] S_AXI_AWPROT, + // Write address valid. This signal indicates that the master signaling + // valid write address and control information. + input wire S_AXI_AWVALID, + // Write address ready. This signal indicates that the slave is ready + // to accept an address and associated control signals. + output wire S_AXI_AWREADY, + // Write data (issued by master, acceped by Slave) + input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA, + // Write strobes. This signal indicates which byte lanes hold + // valid data. There is one write strobe bit for each eight + // bits of the write data bus. + input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB, + // Write valid. This signal indicates that valid write + // data and strobes are available. + input wire S_AXI_WVALID, + // Write ready. This signal indicates that the slave + // can accept the write data. + output wire S_AXI_WREADY, + // Write response. This signal indicates the status + // of the write transaction. + output wire [1 : 0] S_AXI_BRESP, + // Write response valid. This signal indicates that the channel + // is signaling a valid write response. + output wire S_AXI_BVALID, + // Response ready. This signal indicates that the master + // can accept a write response. + input wire S_AXI_BREADY, + // Read address (issued by master, acceped by Slave) + input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR, + // Protection type. This signal indicates the privilege + // and security level of the transaction, and whether the + // transaction is a data access or an instruction access. + input wire [2 : 0] S_AXI_ARPROT, + // Read address valid. This signal indicates that the channel + // is signaling valid read address and control information. + input wire S_AXI_ARVALID, + // Read address ready. This signal indicates that the slave is + // ready to accept an address and associated control signals. + output wire S_AXI_ARREADY, + // Read data (issued by slave) + output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA, + // Read response. This signal indicates the status of the + // read transfer. + output wire [1 : 0] S_AXI_RRESP, + // Read valid. This signal indicates that the channel is + // signaling the required read data. + output wire S_AXI_RVALID, + // Read ready. This signal indicates that the master can + // accept the read data and response information. + input wire S_AXI_RREADY + ); + + // AXI4LITE signals + reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_awaddr; + reg axi_awready; + reg axi_wready; + reg [1 : 0] axi_bresp; + reg axi_bvalid; + reg [C_S_AXI_ADDR_WIDTH-1 : 0] axi_araddr; + reg axi_arready; + reg [C_S_AXI_DATA_WIDTH-1 : 0] axi_rdata; + reg [1 : 0] axi_rresp; + reg axi_rvalid; + + // Example-specific design signals + // local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH + // ADDR_LSB is used for addressing 32/64 bit registers/memories + // ADDR_LSB = 2 for 32 bits (n downto 2) + // ADDR_LSB = 3 for 64 bits (n downto 3) + localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1; + localparam integer OPT_MEM_ADDR_BITS = 2; + //---------------------------------------------- + //-- Signals for user logic register space example + //------------------------------------------------ + //-- Number of Slave Registers 5 + reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg0; + reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg1; + reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg2; + reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg3; + reg [C_S_AXI_DATA_WIDTH-1:0] slv_reg4; + wire slv_reg_rden; + wire slv_reg_wren; + reg [C_S_AXI_DATA_WIDTH-1:0] reg_data_out; + integer byte_index; + + // I/O Connections assignments + + assign S_AXI_AWREADY = axi_awready; + assign S_AXI_WREADY = axi_wready; + assign S_AXI_BRESP = axi_bresp; + assign S_AXI_BVALID = axi_bvalid; + assign S_AXI_ARREADY = axi_arready; + assign S_AXI_RDATA = axi_rdata; + assign S_AXI_RRESP = axi_rresp; + assign S_AXI_RVALID = axi_rvalid; + // Implement axi_awready generation + // axi_awready is asserted for one S_AXI_ACLK clock cycle when both + // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is + // de-asserted when reset is low. + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_awready <= 1'b0; + end + else + begin + if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID) + begin + // slave is ready to accept write address when + // there is a valid write address and write data + // on the write address and data bus. This design + // expects no outstanding transactions. + axi_awready <= 1'b1; + end + else + begin + axi_awready <= 1'b0; + end + end + end + + // Implement axi_awaddr latching + // This process is used to latch the address when both + // S_AXI_AWVALID and S_AXI_WVALID are valid. + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_awaddr <= 0; + end + else + begin + if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID) + begin + // Write Address latching + axi_awaddr <= S_AXI_AWADDR; + end + end + end + + // Implement axi_wready generation + // axi_wready is asserted for one S_AXI_ACLK clock cycle when both + // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is + // de-asserted when reset is low. + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_wready <= 1'b0; + end + else + begin + if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID) + begin + // slave is ready to accept write data when + // there is a valid write address and write data + // on the write address and data bus. This design + // expects no outstanding transactions. + axi_wready <= 1'b1; + end + else + begin + axi_wready <= 1'b0; + end + end + end + + // Implement memory mapped register select and write logic generation + // The write data is accepted and written to memory mapped registers when + // axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to + // select byte enables of slave registers while writing. + // These registers are cleared when reset (active low) is applied. + // Slave register write enable is asserted when valid address and data are available + // and the slave is ready to accept the write address and write data. + assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID; + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + slv_reg0 <= 0; + slv_reg1 <= 0; + slv_reg2 <= 0; + slv_reg3 <= 0; + slv_reg4 <= 0; + end + else begin + if (slv_reg_wren) + begin + case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ) + 3'h0: + for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) + if ( S_AXI_WSTRB[byte_index] == 1 ) begin + // Respective byte enables are asserted as per write strobes + // Slave register 0 + slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; + end + 3'h1: + for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) + if ( S_AXI_WSTRB[byte_index] == 1 ) begin + // Respective byte enables are asserted as per write strobes + // Slave register 1 + slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; + end + 3'h2: + for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) + if ( S_AXI_WSTRB[byte_index] == 1 ) begin + // Respective byte enables are asserted as per write strobes + // Slave register 2 + slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; + end + 3'h3: + for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) + if ( S_AXI_WSTRB[byte_index] == 1 ) begin + // Respective byte enables are asserted as per write strobes + // Slave register 3 + slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; + end + 3'h4: + for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) + if ( S_AXI_WSTRB[byte_index] == 1 ) begin + // Respective byte enables are asserted as per write strobes + // Slave register 4 + slv_reg4[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8]; + end + default : begin + slv_reg0 <= slv_reg0; + slv_reg1 <= slv_reg1; + slv_reg2 <= slv_reg2; + slv_reg3 <= slv_reg3; + slv_reg4 <= slv_reg4; + end + endcase + end + end + end + + // Implement write response logic generation + // The write response and response valid signals are asserted by the slave + // when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. + // This marks the acceptance of address and indicates the status of + // write transaction. + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_bvalid <= 0; + axi_bresp <= 2'b0; + end + else + begin + if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID) + begin + // indicates a valid write response is available + axi_bvalid <= 1'b1; + axi_bresp <= 2'b0; // 'OKAY' response + end // work error responses in future + else + begin + if (S_AXI_BREADY && axi_bvalid) + //check if bready is asserted while bvalid is high) + //(there is a possibility that bready is always asserted high) + begin + axi_bvalid <= 1'b0; + end + end + end + end + + // Implement axi_arready generation + // axi_arready is asserted for one S_AXI_ACLK clock cycle when + // S_AXI_ARVALID is asserted. axi_awready is + // de-asserted when reset (active low) is asserted. + // The read address is also latched when S_AXI_ARVALID is + // asserted. axi_araddr is reset to zero on reset assertion. + + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_arready <= 1'b0; + axi_araddr <= 32'b0; + end + else + begin + if (~axi_arready && S_AXI_ARVALID) + begin + // indicates that the slave has acceped the valid read address + axi_arready <= 1'b1; + // Read address latching + axi_araddr <= S_AXI_ARADDR; + end + else + begin + axi_arready <= 1'b0; + end + end + end + + // Implement axi_arvalid generation + // axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both + // S_AXI_ARVALID and axi_arready are asserted. The slave registers + // data are available on the axi_rdata bus at this instance. The + // assertion of axi_rvalid marks the validity of read data on the + // bus and axi_rresp indicates the status of read transaction.axi_rvalid + // is deasserted on reset (active low). axi_rresp and axi_rdata are + // cleared to zero on reset (active low). + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_rvalid <= 0; + axi_rresp <= 0; + end + else + begin + if (axi_arready && S_AXI_ARVALID && ~axi_rvalid) + begin + // Valid read data is available at the read data bus + axi_rvalid <= 1'b1; + axi_rresp <= 2'b0; // 'OKAY' response + end + else if (axi_rvalid && S_AXI_RREADY) + begin + // Read data is accepted by the master + axi_rvalid <= 1'b0; + end + end + end + + // Implement memory mapped register select and read logic generation + // Slave register read enable is asserted when valid address is available + // and the slave is ready to accept the read address. + assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid; + always @(*) + begin + // Address decoding for reading registers + case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] ) + 3'h0 : reg_data_out <= slv_reg0; + 3'h1 : reg_data_out <= slv_reg1; + 3'h2 : reg_data_out <= slv_reg2; + 3'h3 : reg_data_out <= slv_reg3; + 3'h4 : reg_data_out <= slv_reg4; + default : reg_data_out <= 0; + endcase + end + + // Output register or memory read data + always @( posedge S_AXI_ACLK ) + begin + if ( S_AXI_ARESETN == 1'b0 ) + begin + axi_rdata <= 0; + end + else + begin + // When there is a valid read address (S_AXI_ARVALID) with + // acceptance of read address by the slave (axi_arready), + // output the read dada + if (slv_reg_rden) + begin + axi_rdata <= reg_data_out; // register read data + end + end + end + + // Add user logic here + + // User logic ends + + endmodule diff --git a/src/blitter.v b/src/blitter.v new file mode 100644 index 0000000..691893a --- /dev/null +++ b/src/blitter.v @@ -0,0 +1,267 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Engineer: Sergiusz Bazanski +// Licensed under BSD 2-Clause, see COPYING. +// +// Create Date: 11/10/2015 10:42:10 PM +// Design Name: +// Module Name: blitter +// Project Name: LED Controller for GRAET JUSTICE +// Target Devices: MYiR ZTurn Board with Zynq-7010 +// Tool Versions: +// Description: +// +// Dependencies: +// +// +////////////////////////////////////////////////////////////////////////////////// +module blitter #( + // Number of display chains + parameter integer C_LED_CHAINS = 4, + // Maximum length of display chain + parameter integer C_LED_CHAIN_LENGTH = 4, + // Number of banks in one chain + parameter integer C_LED_NBANKS = 16, + // Width of one display + parameter integer C_LED_WIDTH = 32, + // Clock divider from system clock to LED blit clock + parameter integer C_LED_CLKDIV = 10, + // Bits per pixel colour + parameter integer C_BPC = 8 +) +( + // TODO: change to target config registers + /*input [31:0] bufa_base, + input [31:0] bufa_limit, + input [31:0] bufb_base, + input [31:0] bufb_limit, + input buf_sel,*/ + + input sys_en, + input sys_clk, + input sys_rst, + + output reg led_clk, + output reg led_stb, + output led_oe, + output [$clog2(C_LED_NBANKS)-1 : 0] led_bank + // This module is currently hardcoded to be C_LED_NBANKS * 2 high (so be '1 / C_LED_NBANKS scan') + /*output [C_LED_CHAIN_LENGTH-1 : 0] led_r0, + output [C_LED_CHAIN_LENGTH-1 : 0] led_r1, + output [C_LED_CHAIN_LENGTH-1 : 0] led_g0, + output [C_LED_CHAIN_LENGTH-1 : 0] led_g1, + output [C_LED_CHAIN_LENGTH-1 : 0] led_b0, + output [C_LED_CHAIN_LENGTH-1 : 0] led_b1, + output [C_LED_NBANKS-1 : 0] led_bank*/ +); + +/// Counters +// Current line pixel counter +reg [$clog2(C_LED_WIDTH * C_LED_CHAIN_LENGTH)-1 : 0] pixel_counter; +// Frame bank counter +reg [$clog2(C_LED_NBANKS)-1 : 0] bank_counter; +assign led_bank = bank_counter; +// Individual pixel divider +reg [$clog2(C_LED_CLKDIV)-1 : 0] divider_counter; +// Subframe counter (for pixel bits) +reg [$clog2(C_BPC)-1 : 0] subframe_counter; + +/// Internal condition signals +// Are we blitting out the last pixel in the current line? +wire last_pixel = (pixel_counter >= (C_LED_WIDTH * C_LED_CHAIN_LENGTH) - 1); +// Are we blitting out the last line in the current subframe? +wire last_line = (bank_counter >= C_LED_NBANKS - 1); +// Are we blitting out the last subframe in the frame? +wire last_subframe = (subframe_counter >= C_BPC - 1); + +/// Line FSM +// Idle +`define LINE_IDLE 3'b000 +// Preparation before first pixel of line +`define LINE_PREPARE_FOR_BURST 3'b001 +// Burst out a pixel, switch to next one if divider counter reaches zero +`define LINE_BURST 3'b010 +// Wait for latch confirmation +`define LINE_WAIT_FOR_CONFIRMATION 3'b011 +// Latch out this row, +`define LINE_LATCH 3'b100 +reg [2:0] line_fsm_state; +wire line_fsm_start; +reg line_fsm_busy; +assign led_oe = line_fsm_busy; +always @(posedge sys_clk or negedge sys_rst) +begin + if (~sys_rst) begin + /// Reset counters + // New output period + divider_counter <= 0; + // New column + pixel_counter <= 0; + // New row + bank_counter <= 0; + + line_fsm_busy <= 0; + line_fsm_state <= `LINE_IDLE; + end else begin + case (line_fsm_state) + `LINE_IDLE: begin + // Two-step for potential clock domain cross + if (~line_fsm_busy) begin + if (line_fsm_start) begin + line_fsm_busy <= 1; + end else begin + line_fsm_busy <= 0; + end + end else begin + line_fsm_state <= `LINE_PREPARE_FOR_BURST; + end + end + `LINE_PREPARE_FOR_BURST: begin + // Begin new pixel + divider_counter <= C_LED_CLKDIV - 1; + // Begin new row + pixel_counter <= 0; + + // Set outputs + led_clk <= 0; + led_stb <= 0; + + line_fsm_state <= `LINE_BURST; + end + `LINE_BURST: begin + // Count down divider_counter, increment pixel_counter on underflow + if (divider_counter == 0) begin + // Count up pixel counter, see if we blitted all pixels in this row + if (last_pixel) begin + pixel_counter <= 0; + line_fsm_state <= `LINE_LATCH; + end else begin + pixel_counter <= pixel_counter + 1; + end + divider_counter <= C_LED_CLKDIV - 1; + end else begin + divider_counter <= divider_counter - 1; + end + // Stretch LED clock accross countdown domain (so that we clock out the data in the middle of the period) + // _______ _______ + // | | | | + // clk ______| |______| |____ + // dat ><=============><=============><===== + // ctr 80---------> 0 80 --------> 0 80 ---- + if (divider_counter < (C_LED_CLKDIV / 2)) + led_clk <= 0; + else + led_clk <= 1; + end + `LINE_LATCH: begin + // Cleanup after previous state... + led_clk <= 0; + + if (divider_counter == 0) begin + if (last_line) begin + line_fsm_state <= `LINE_IDLE; + line_fsm_busy <= 0; + bank_counter <= 0; + end else begin + line_fsm_state <= `LINE_PREPARE_FOR_BURST; + bank_counter <= bank_counter + 1; + end + end else begin + divider_counter <= divider_counter - 1; + end + + if (divider_counter < (C_LED_CLKDIV / 2)) + led_stb <= 0; + else + led_stb <= 1; + end + endcase + end +end + +/// Subframe FSM +`define SUBFRAME_IDLE 3'b000 +`define SUBFRAME_CALIBRATE 3'b001 +`define SUBFRAME_CALIBRATE2 3'b010 +`define SUBFRAME_WAIT 3'b011 +`define SUBFRAME_WAIT2 3'b100 +reg [2:0] subframe_fsm_state; + +// Create some register for Line FSM control lines +reg subframe_line_start; +assign line_fsm_start = subframe_line_start; + +// Delay counter for subframe, and calibration counter (for first, smaller interval) +// We need to do some calculations... this should be able to fit +// 2**C_BPC * (C_LED_WIDTH * C_LED_CHAIN_LENGTH) * C_LED_CLKDIV * C_LED_NBANKS * 2 +// | | | | \____ convservative guesstimate :v +// | | | \____ bank count +// | | \____ amounts of sysclocks we spend on a pixel +// | \___ number of LEDs we drive in one line +// \___ bits per pixel timeslot change (if shortest period is X, longest is X * 2**C_BPC) +reg [$clog2(2**C_BPC * (C_LED_WIDTH * C_LED_CHAIN_LENGTH) * C_LED_CLKDIV * C_LED_NBANKS * 2)-1: 0] subframe_delay; +reg [$clog2((C_LED_WIDTH * C_LED_CHAIN_LENGTH) * C_LED_CLKDIV * C_LED_NBANKS * 2)-1: 0] subframe_calibration_delay; + +always @(posedge sys_clk or negedge sys_rst) +begin + if (~sys_rst) begin + subframe_counter <= 0; + subframe_calibration_delay <= 0; + subframe_delay <= 0; + + subframe_line_start <= 0; + subframe_fsm_state <= `SUBFRAME_IDLE; + end else begin + case (subframe_fsm_state) + `SUBFRAME_IDLE: begin + if (!line_fsm_busy) begin + subframe_line_start <= 1; + if (subframe_counter == 0) begin + // we're running the first, smallest subframe interval - start calibration + subframe_fsm_state <= `SUBFRAME_CALIBRATE; + subframe_delay <= 0; + end else begin + subframe_fsm_state <= `SUBFRAME_WAIT; + subframe_delay <= (subframe_calibration_delay << subframe_counter); + end + end else begin + end + end + `SUBFRAME_CALIBRATE: begin + subframe_line_start <= 0; + subframe_calibration_delay <= 0; + subframe_fsm_state <= `SUBFRAME_CALIBRATE2; + end + `SUBFRAME_CALIBRATE2: begin + if (!line_fsm_busy) begin + subframe_calibration_delay <= (subframe_calibration_delay >> 1); + subframe_delay <= ((subframe_calibration_delay>>1) << subframe_counter); + subframe_fsm_state <= `SUBFRAME_WAIT2; + end else begin + subframe_calibration_delay <= subframe_calibration_delay + 1; + end + end + `SUBFRAME_WAIT: begin + subframe_line_start <= 0; + subframe_fsm_state <= `SUBFRAME_WAIT2; + end + `SUBFRAME_WAIT2: begin + if (!line_fsm_busy) begin + if (subframe_delay == 0) begin + subframe_fsm_state <= `SUBFRAME_IDLE; + + if (last_line) begin + subframe_counter <= 0; + end else begin + subframe_counter <= subframe_counter + 1; + end + end else begin + subframe_delay <= subframe_delay - 1; + end + end + end + endcase + end +end + +endmodule