diff --git a/.gitmodules b/.gitmodules index df2166d3a8dd621fab4365e9cd0cc8502c410496..9928787c6a9a1ee668c29a4e61c9258fc23dab22 100644 --- a/.gitmodules +++ b/.gitmodules @@ -46,3 +46,6 @@ [submodule "src/rv_plic"] path = src/rv_plic url = https://github.com/pulp-platform/rv_plic.git +[submodule "fpga/src/apb_timer"] + path = fpga/src/apb_timer + url = https://github.com/pulp-platform/apb_timer.git diff --git a/Bender.yml b/Bender.yml index 727892f56479372d16192ec79c78f0d9243d65f4..8dfe9e1f10c58344f9f60bbccbe12c720eb5c425 100644 --- a/Bender.yml +++ b/Bender.yml @@ -111,6 +111,8 @@ sources: - fpga/src/axi_slice/src/axi_ar_buffer.sv - fpga/src/axi_slice/src/axi_r_buffer.sv - fpga/src/axi_slice/src/axi_aw_buffer.sv + - fpga/src/apb_timer/apb_timer.sv + - fpga/src/apb_timer/timer.sv - src/axi_node/src/axi_regs_top.sv - src/axi_node/src/axi_BR_allocator.sv - src/axi_node/src/axi_BW_allocator.sv diff --git a/Makefile b/Makefile index 9693a5fc6a61d81a8221e51056ee4065054bdf11..0957459c1da580f5bd2e85c344e0bbfc9d5df590 100644 --- a/Makefile +++ b/Makefile @@ -131,6 +131,7 @@ src := $(filter-out src/ariane_regfile.sv, $(wildcard src/*.sv)) \ $(wildcard bootrom/*.sv) \ $(wildcard src/clint/*.sv) \ $(wildcard fpga/src/axi2apb/src/*.sv) \ + $(wildcard fpga/src/apb_timer/*.sv) \ $(wildcard fpga/src/axi_slice/src/*.sv) \ $(wildcard src/axi_node/src/*.sv) \ $(wildcard src/axi_riscv_atomics/src/*.sv) \ diff --git a/bootrom/ariane.dts b/bootrom/ariane.dts index 9cd2df99f297c62372f2e8d2d0cc464ae2309431..54c9af0e6a507a73db6847d1d84c097d7c618777 100644 --- a/bootrom/ariane.dts +++ b/bootrom/ariane.dts @@ -68,5 +68,12 @@ reg-shift = <2>; // regs are spaced on 32 bit boundary reg-io-width = <4>; // only 32-bit access are supported }; + timer@18000000 { + compatible = "pulp,apb_timer"; + interrupts = <0x00000004 0x00000005 0x00000006 0x00000007>; + reg = <0x00000000 0x18000000 0x00000000 0x00001000>; + // interrupt-parent = <&PLIC0>; + reg-names = "control"; + }; }; }; diff --git a/fpga/src/apb_timer b/fpga/src/apb_timer new file mode 160000 index 0000000000000000000000000000000000000000..6c84f69d2e92bd766f609b5dd47ece723359bd24 --- /dev/null +++ b/fpga/src/apb_timer @@ -0,0 +1 @@ +Subproject commit 6c84f69d2e92bd766f609b5dd47ece723359bd24 diff --git a/fpga/src/ariane_peripherals_xilinx.sv b/fpga/src/ariane_peripherals_xilinx.sv index 55ee73c1eff2fce9de52ade1a9fce3465f93754e..06501847952a9baa36a899e0e7c4bcd1f9f6e788 100644 --- a/fpga/src/ariane_peripherals_xilinx.sv +++ b/fpga/src/ariane_peripherals_xilinx.sv @@ -18,7 +18,8 @@ module ariane_peripherals #( parameter bit InclUART = 1, parameter bit InclSPI = 0, parameter bit InclEthernet = 0, - parameter bit InclGPIO = 0 + parameter bit InclGPIO = 0, + parameter bit InclTimer = 1 ) ( input logic clk_i , // Clock input logic clk_200MHz_i , @@ -28,6 +29,7 @@ module ariane_peripherals #( AXI_BUS.Slave spi , AXI_BUS.Slave gpio , AXI_BUS.Slave ethernet , + AXI_BUS.Slave timer , output logic [1:0] irq_o , // UART input logic rx_i , @@ -732,4 +734,99 @@ module ariane_peripherals #( assign s_axi_gpio_rlast = 1'b1; assign s_axi_gpio_wlast = 1'b1; end + + // 6. Timer + if (InclTimer) begin : gen_timer + logic timer_penable; + logic timer_pwrite; + logic [31:0] timer_paddr; + logic timer_psel; + logic [31:0] timer_pwdata; + logic [31:0] timer_prdata; + logic timer_pready; + logic timer_pslverr; + + axi2apb_64_32 #( + .AXI4_ADDRESS_WIDTH ( AxiAddrWidth ), + .AXI4_RDATA_WIDTH ( AxiDataWidth ), + .AXI4_WDATA_WIDTH ( AxiDataWidth ), + .AXI4_ID_WIDTH ( AxiIdWidth ), + .AXI4_USER_WIDTH ( AxiUserWidth ), + .BUFF_DEPTH_SLAVE ( 2 ), + .APB_ADDR_WIDTH ( 32 ) + ) i_axi2apb_64_32_timer ( + .ACLK ( clk_i ), + .ARESETn ( rst_ni ), + .test_en_i ( 1'b0 ), + .AWID_i ( timer.aw_id ), + .AWADDR_i ( timer.aw_addr ), + .AWLEN_i ( timer.aw_len ), + .AWSIZE_i ( timer.aw_size ), + .AWBURST_i ( timer.aw_burst ), + .AWLOCK_i ( timer.aw_lock ), + .AWCACHE_i ( timer.aw_cache ), + .AWPROT_i ( timer.aw_prot ), + .AWREGION_i( timer.aw_region ), + .AWUSER_i ( timer.aw_user ), + .AWQOS_i ( timer.aw_qos ), + .AWVALID_i ( timer.aw_valid ), + .AWREADY_o ( timer.aw_ready ), + .WDATA_i ( timer.w_data ), + .WSTRB_i ( timer.w_strb ), + .WLAST_i ( timer.w_last ), + .WUSER_i ( timer.w_user ), + .WVALID_i ( timer.w_valid ), + .WREADY_o ( timer.w_ready ), + .BID_o ( timer.b_id ), + .BRESP_o ( timer.b_resp ), + .BVALID_o ( timer.b_valid ), + .BUSER_o ( timer.b_user ), + .BREADY_i ( timer.b_ready ), + .ARID_i ( timer.ar_id ), + .ARADDR_i ( timer.ar_addr ), + .ARLEN_i ( timer.ar_len ), + .ARSIZE_i ( timer.ar_size ), + .ARBURST_i ( timer.ar_burst ), + .ARLOCK_i ( timer.ar_lock ), + .ARCACHE_i ( timer.ar_cache ), + .ARPROT_i ( timer.ar_prot ), + .ARREGION_i( timer.ar_region ), + .ARUSER_i ( timer.ar_user ), + .ARQOS_i ( timer.ar_qos ), + .ARVALID_i ( timer.ar_valid ), + .ARREADY_o ( timer.ar_ready ), + .RID_o ( timer.r_id ), + .RDATA_o ( timer.r_data ), + .RRESP_o ( timer.r_resp ), + .RLAST_o ( timer.r_last ), + .RUSER_o ( timer.r_user ), + .RVALID_o ( timer.r_valid ), + .RREADY_i ( timer.r_ready ), + .PENABLE ( timer_penable ), + .PWRITE ( timer_pwrite ), + .PADDR ( timer_paddr ), + .PSEL ( timer_psel ), + .PWDATA ( timer_pwdata ), + .PRDATA ( timer_prdata ), + .PREADY ( timer_pready ), + .PSLVERR ( timer_pslverr ) + ); + + apb_timer #( + .APB_ADDR_WIDTH ( 32 ), + .TIMER_CNT ( 2 ) + ) i_timer ( + .HCLK ( clk_i ), + .HRESETn ( rst_ni ), + .PSEL ( timer_psel ), + .PENABLE ( timer_penable ), + .PWRITE ( timer_pwrite ), + .PADDR ( timer_paddr ), + .PWDATA ( timer_pwdata ), + .PRDATA ( timer_prdata ), + .PREADY ( timer_pready ), + .PSLVERR ( timer_pslverr ), + .irq_o ( irq_sources[6:3] ) + ); + end endmodule diff --git a/fpga/src/ariane_xilinx.sv b/fpga/src/ariane_xilinx.sv index c895d8c8c8d36571473e88ee2ba80b268840dd34..f633d62202da2dce411744e0f626590f04e35b78 100644 --- a/fpga/src/ariane_xilinx.sv +++ b/fpga/src/ariane_xilinx.sv @@ -269,6 +269,7 @@ axi_node_wrap_with_slices #( ariane_soc::CLINTBase, ariane_soc::PLICBase, ariane_soc::UARTBase, + ariane_soc::TimerBase, ariane_soc::SPIBase, ariane_soc::EthernetBase, ariane_soc::GPIOBase, @@ -280,6 +281,7 @@ axi_node_wrap_with_slices #( ariane_soc::CLINTBase + ariane_soc::CLINTLength - 1, ariane_soc::PLICBase + ariane_soc::PLICLength - 1, ariane_soc::UARTBase + ariane_soc::UARTLength - 1, + ariane_soc::TimerBase + ariane_soc::TimerLength - 1, ariane_soc::SPIBase + ariane_soc::SPILength - 1, ariane_soc::EthernetBase + ariane_soc::EthernetLength -1, ariane_soc::GPIOBase + ariane_soc::GPIOLength - 1, @@ -534,6 +536,7 @@ ariane_peripherals #( .gpio ( master[ariane_soc::GPIO] ), .eth_clk_i ( eth_clk ), .ethernet ( master[ariane_soc::Ethernet] ), + .timer ( master[ariane_soc::Timer] ), .irq_o ( irq ), .rx_i ( rx ), .tx_o ( tx ), diff --git a/fpga/src/bootrom/ariane.dts b/fpga/src/bootrom/ariane.dts index 59ee3341a7c04edcdcfa984fcd11d52e2c560b03..0f0e943496a48bd1fbf30d7b5c9cf832a7fc1bf1 100644 --- a/fpga/src/bootrom/ariane.dts +++ b/fpga/src/bootrom/ariane.dts @@ -60,7 +60,7 @@ interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9>; reg = <0x0 0xc000000 0x0 0x4000000>; riscv,max-priority = <7>; - riscv,ndev = <3>; + riscv,ndev = <30>; }; debug-controller@0 { compatible = "riscv,debug-013"; @@ -78,6 +78,13 @@ reg-shift = <2>; // regs are spaced on 32 bit boundary reg-io-width = <4>; // only 32-bit access are supported }; + timer@18000000 { + compatible = "pulp,apb_timer"; + interrupts = <0x00000004 0x00000005 0x00000006 0x00000007>; + reg = <0x00000000 0x18000000 0x00000000 0x00001000>; + interrupt-parent = <&PLIC0>; + reg-names = "control"; + }; xps-spi@20000000 { compatible = "xlnx,xps-spi-2.00.b", "xlnx,xps-spi-2.00.a"; #address-cells = <1>; diff --git a/src_files.yml b/src_files.yml index a5e7fd259d005e4140c56950faf4ab5f4acf2220..0a150f3aa1493e40a849dd49565e314923a0454c 100644 --- a/src_files.yml +++ b/src_files.yml @@ -54,6 +54,8 @@ ariane: src/debug/dmi_cdc.sv, src/debug/dmi_jtag.sv, src/debug/dmi_jtag_tap.sv, + fpga/apb_timer/apb_timer.sv, + fpga/apb_timer/timer.sv, ] riscv_regfile_rtl: targets: [ diff --git a/tb/ariane_peripherals.sv b/tb/ariane_peripherals.sv index 13ec46f38e67bcf57e70e1a8effe7ee7eef33e69..9f9f76c425ffc6700aa084d97d306b1f77878e24 100644 --- a/tb/ariane_peripherals.sv +++ b/tb/ariane_peripherals.sv @@ -17,7 +17,8 @@ module ariane_peripherals #( parameter bit InclUART = 1, parameter bit InclSPI = 0, parameter bit InclEthernet = 0, - parameter bit InclGPIO = 0 + parameter bit InclGPIO = 0, + parameter bit InclTimer = 1 ) ( input logic clk_i , // Clock input logic rst_ni , // Asynchronous reset active low @@ -25,6 +26,7 @@ module ariane_peripherals #( AXI_BUS.Slave uart , AXI_BUS.Slave spi , AXI_BUS.Slave ethernet , + AXI_BUS.Slave timer , output logic [1:0] irq_o , // UART input logic rx_i , @@ -515,4 +517,101 @@ module ariane_peripherals #( assign ethernet.r_data = 'hdeadbeef; assign ethernet.r_last = 1'b1; end + + // --------------- + // 5. Timer + // --------------- + if (InclTimer) begin : gen_timer + logic timer_penable; + logic timer_pwrite; + logic [31:0] timer_paddr; + logic timer_psel; + logic [31:0] timer_pwdata; + logic [31:0] timer_prdata; + logic timer_pready; + logic timer_pslverr; + + axi2apb_64_32 #( + .AXI4_ADDRESS_WIDTH ( AxiAddrWidth ), + .AXI4_RDATA_WIDTH ( AxiDataWidth ), + .AXI4_WDATA_WIDTH ( AxiDataWidth ), + .AXI4_ID_WIDTH ( AxiIdWidth ), + .AXI4_USER_WIDTH ( AxiUserWidth ), + .BUFF_DEPTH_SLAVE ( 2 ), + .APB_ADDR_WIDTH ( 32 ) + ) i_axi2apb_64_32_timer ( + .ACLK ( clk_i ), + .ARESETn ( rst_ni ), + .test_en_i ( 1'b0 ), + .AWID_i ( timer.aw_id ), + .AWADDR_i ( timer.aw_addr ), + .AWLEN_i ( timer.aw_len ), + .AWSIZE_i ( timer.aw_size ), + .AWBURST_i ( timer.aw_burst ), + .AWLOCK_i ( timer.aw_lock ), + .AWCACHE_i ( timer.aw_cache ), + .AWPROT_i ( timer.aw_prot ), + .AWREGION_i( timer.aw_region ), + .AWUSER_i ( timer.aw_user ), + .AWQOS_i ( timer.aw_qos ), + .AWVALID_i ( timer.aw_valid ), + .AWREADY_o ( timer.aw_ready ), + .WDATA_i ( timer.w_data ), + .WSTRB_i ( timer.w_strb ), + .WLAST_i ( timer.w_last ), + .WUSER_i ( timer.w_user ), + .WVALID_i ( timer.w_valid ), + .WREADY_o ( timer.w_ready ), + .BID_o ( timer.b_id ), + .BRESP_o ( timer.b_resp ), + .BVALID_o ( timer.b_valid ), + .BUSER_o ( timer.b_user ), + .BREADY_i ( timer.b_ready ), + .ARID_i ( timer.ar_id ), + .ARADDR_i ( timer.ar_addr ), + .ARLEN_i ( timer.ar_len ), + .ARSIZE_i ( timer.ar_size ), + .ARBURST_i ( timer.ar_burst ), + .ARLOCK_i ( timer.ar_lock ), + .ARCACHE_i ( timer.ar_cache ), + .ARPROT_i ( timer.ar_prot ), + .ARREGION_i( timer.ar_region ), + .ARUSER_i ( timer.ar_user ), + .ARQOS_i ( timer.ar_qos ), + .ARVALID_i ( timer.ar_valid ), + .ARREADY_o ( timer.ar_ready ), + .RID_o ( timer.r_id ), + .RDATA_o ( timer.r_data ), + .RRESP_o ( timer.r_resp ), + .RLAST_o ( timer.r_last ), + .RUSER_o ( timer.r_user ), + .RVALID_o ( timer.r_valid ), + .RREADY_i ( timer.r_ready ), + .PENABLE ( timer_penable ), + .PWRITE ( timer_pwrite ), + .PADDR ( timer_paddr ), + .PSEL ( timer_psel ), + .PWDATA ( timer_pwdata ), + .PRDATA ( timer_prdata ), + .PREADY ( timer_pready ), + .PSLVERR ( timer_pslverr ) + ); + + apb_timer #( + .APB_ADDR_WIDTH ( 32 ), + .TIMER_CNT ( 2 ) + ) i_timer ( + .HCLK ( clk_i ), + .HRESETn ( rst_ni ), + .PSEL ( timer_psel ), + .PENABLE ( timer_penable ), + .PWRITE ( timer_pwrite ), + .PADDR ( timer_paddr ), + .PWDATA ( timer_pwdata ), + .PRDATA ( timer_prdata ), + .PREADY ( timer_pready ), + .PSLVERR ( timer_pslverr ), + .irq_o ( irq_sources[6:3] ) + ); + end endmodule diff --git a/tb/ariane_soc_pkg.sv b/tb/ariane_soc_pkg.sv index 4e0ef3aa48212e48a474430e218c2310dc5d4593..8f522a2e1b9a38f28db4cc1322e0a36b6984d5a1 100644 --- a/tb/ariane_soc_pkg.sv +++ b/tb/ariane_soc_pkg.sv @@ -28,11 +28,12 @@ package ariane_soc; GPIO = 1, Ethernet = 2, SPI = 3, - UART = 4, - PLIC = 5, - CLINT = 6, - ROM = 7, - Debug = 8 + Timer = 4, + UART = 5, + PLIC = 6, + CLINT = 7, + ROM = 8, + Debug = 9 } axi_slaves_t; localparam NB_PERIPHERALS = Debug + 1; @@ -43,6 +44,7 @@ package ariane_soc; localparam logic[63:0] CLINTLength = 64'hC0000; localparam logic[63:0] PLICLength = 64'h3FF_FFFF; localparam logic[63:0] UARTLength = 64'h1000; + localparam logic[63:0] TimerLength = 64'h1000; localparam logic[63:0] SPILength = 64'h800000; localparam logic[63:0] EthernetLength = 64'h10000; localparam logic[63:0] GPIOLength = 64'h1000; @@ -57,6 +59,7 @@ package ariane_soc; CLINTBase = 64'h0200_0000, PLICBase = 64'h0C00_0000, UARTBase = 64'h1000_0000, + TimerBase = 64'h1800_0000, SPIBase = 64'h2000_0000, EthernetBase = 64'h3000_0000, GPIOBase = 64'h4000_0000, diff --git a/tb/ariane_testharness.sv b/tb/ariane_testharness.sv index fec1e22a573da9df6cc5f98e009aaf7e85d2070b..075a305b9f3a836baceaf86e6be853306fa99ef8 100644 --- a/tb/ariane_testharness.sv +++ b/tb/ariane_testharness.sv @@ -551,6 +551,7 @@ module ariane_testharness #( ariane_soc::CLINTBase, ariane_soc::PLICBase, ariane_soc::UARTBase, + ariane_soc::TimerBase, ariane_soc::SPIBase, ariane_soc::EthernetBase, ariane_soc::GPIOBase, @@ -562,6 +563,7 @@ module ariane_testharness #( ariane_soc::CLINTBase + ariane_soc::CLINTLength - 1, ariane_soc::PLICBase + ariane_soc::PLICLength - 1, ariane_soc::UARTBase + ariane_soc::UARTLength - 1, + ariane_soc::TimerBase + ariane_soc::TimerLength - 1, ariane_soc::SPIBase + ariane_soc::SPILength - 1, ariane_soc::EthernetBase + ariane_soc::EthernetLength -1, ariane_soc::GPIOBase + ariane_soc::GPIOLength - 1, @@ -630,6 +632,7 @@ module ariane_testharness #( .uart ( master[ariane_soc::UART] ), .spi ( master[ariane_soc::SPI] ), .ethernet ( master[ariane_soc::Ethernet] ), + .timer ( master[ariane_soc::Timer] ), .irq_o ( irqs ), .rx_i ( rx ), .tx_o ( tx ),