From 385f152ad56a957469a824890521fb26b05cbce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Sat, 27 Dec 2025 11:53:16 +0100 Subject: [PATCH] Add pll to the system on chip --- CMakeLists.txt | 25 ++++++++++--- config/pinout.lpf | 6 +-- firmware/bootloader/uart.S | 2 +- src/ecap5_dsoc.sv | 43 +++++++++++++--------- src/poweron_reset.sv | 42 --------------------- tests/CMakeLists.txt | 28 +++++++++++++- tests/benches/ecap5_dsoc/tb_ecap5_dsoc.cpp | 8 ++-- tests/benches/ecap5_dsoc/tb_ecap5_dsoc.sv | 4 +- 8 files changed, 83 insertions(+), 75 deletions(-) delete mode 100644 src/poweron_reset.sv diff --git a/CMakeLists.txt b/CMakeLists.txt index 166df1e..3d9469a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,11 +83,10 @@ add_dependency( GIT ecap5/ecap5-dwbspi TAG release/v1.0.0) -# Define an interface library +# Define an interface library for the sources add_library(ecap5_dsoc INTERFACE) target_sources(ecap5_dsoc INTERFACE ${CMAKE_CURRENT_LIST_DIR}/src/ecap5_dsoc.sv - ${CMAKE_CURRENT_LIST_DIR}/src/poweron_reset.sv ) target_link_libraries(ecap5_dsoc INTERFACE ecap5_dproc @@ -113,15 +112,31 @@ if(PROJECT_IS_TOP_LEVEL) add_subdirectory(firmware) add_subdirectory(tests) + # Define an interface library for the bitstream generation + add_library(ecap5_dsoc_bitstream INTERFACE) + target_sources(ecap5_dsoc_bitstream INTERFACE + ${CMAKE_BINARY_DIR}/generated_pll.v + ) + target_link_libraries(ecap5_dsoc_bitstream INTERFACE + ecap5_dsoc + ) + # Bitstream generation + set(CLOCK_FREQUENCY 60) + add_ecp5_pll_generation( + INPUT_FREQ 24 + OUTPUT_FREQ ${CLOCK_FREQUENCY} + MODULE_NAME generated_pll) + add_synthesis_target( - LIB ecap5_dsoc + LIB ecap5_dsoc_bitstream TOP_MODULE ecap5_dsoc TARGET_FPGA ecp5 OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/synth.json - DEPENDS bootloader - DEFINES BOOTLOADER_PATH=\\\"${CMAKE_CURRENT_BINARY_DIR}/firmware/bootloader.load\\\") + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated_pll.v bootloader + DEFINES BOOTLOADER_PATH=\\\"${CMAKE_CURRENT_BINARY_DIR}/firmware/bootloader.load\\\" + CLK_FREQ=${CLOCK_FREQUENCY}000000) add_place_and_route_target( INPUT ${CMAKE_CURRENT_BINARY_DIR}/synth.json diff --git a/config/pinout.lpf b/config/pinout.lpf index c343d13..b2d2632 100644 --- a/config/pinout.lpf +++ b/config/pinout.lpf @@ -4,10 +4,10 @@ # Oscillator input - LOCATE COMP "clk_i" SITE "P5"; + LOCATE COMP "ext_clk_i" SITE "P5"; - PORT "clk_i" IO_TYPE=LVCMOS33; - FREQUENCY PORT "clk_i" 24 MHZ; + PORT "ext_clk_i" IO_TYPE=LVCMOS33; + FREQUENCY PORT "ext_clk_i" 24 MHZ; # Power monitoring - SPI diff --git a/firmware/bootloader/uart.S b/firmware/bootloader/uart.S index ebfb0a1..275b234 100644 --- a/firmware/bootloader/uart.S +++ b/firmware/bootloader/uart.S @@ -30,7 +30,7 @@ .equ UART_DS_MASK, (1 << 3) .equ UART_TXE_MASK, (1 << 1) -.equ UART_ACC_INCR, 26 +.equ UART_ACC_INCR, 10 .equ UART_DS, 1 .section .text diff --git a/src/ecap5_dsoc.sv b/src/ecap5_dsoc.sv index f67a096..b372966 100644 --- a/src/ecap5_dsoc.sv +++ b/src/ecap5_dsoc.sv @@ -20,8 +20,12 @@ * along with ECAP5-DSOC. If not, see . */ +`ifndef CLK_FREQ + `define CLK_FREQ 24000000 +`endif + module ecap5_dsoc ( - input logic clk_i, + input logic ext_clk_i, //================================= // UART interface @@ -61,8 +65,8 @@ module ecap5_dsoc ( output logic emmc_rst_n ); -// poweron-reset -logic por_rst; +// PLL signals +logic clk, rst, pll_locked; // core master memory bus logic[31:0] core_wb_adr_o; @@ -123,16 +127,17 @@ logic flash_wb_stall_o; logic flash_clk; logic flash_cs; -poweron_reset por_inst ( - .clk_i (clk_i), - .rst_o (por_rst) +generated_pll pll_inst ( + .clkin (ext_clk_i), + .clkout0 (clk), + .locked (pll_locked) ); ecap5_dproc #( .BOOT_ADDRESS (32'h0) ) core_inst ( - .clk_i (clk_i), - .rst_i (por_rst), + .clk_i (clk), + .rst_i (rst), .wb_adr_o (core_wb_adr_o), .wb_dat_i (core_wb_dat_i), @@ -146,8 +151,8 @@ ecap5_dproc #( ); ecap5_dwbuart uart_inst ( - .clk_i (clk_i), - .rst_i (por_rst), + .clk_i (clk), + .rst_i (rst), .wb_adr_i (uart_wb_adr_i), .wb_dat_o (uart_wb_dat_o), @@ -168,8 +173,8 @@ ecap5_dwbmem_bram #( .ENABLE_PRELOADING (1), .PRELOAD_HEX_PATH (`BOOTLOADER_PATH) ) bram_inst ( - .clk_i (clk_i), - .rst_i (por_rst), + .clk_i (clk), + .rst_i (rst), .wb_adr_i (bram_wb_adr_i), .wb_dat_o (bram_wb_dat_o), @@ -183,10 +188,10 @@ ecap5_dwbmem_bram #( ); ecap5_dwbtimer #( - .CLK_FREQ (24000000) + .CLK_FREQ (`CLK_FREQ) ) timer_inst ( - .clk_i (clk_i), - .rst_i (por_rst), + .clk_i (clk), + .rst_i (rst), .wb_adr_i (timer_wb_adr_i), .wb_dat_o (timer_wb_dat_o), @@ -201,8 +206,8 @@ ecap5_dwbtimer #( ecap5_dwbspi #( ) flash_inst ( - .clk_i (clk_i), - .rst_i (por_rst), + .clk_i (clk), + .rst_i (rst), .wb_adr_i (flash_wb_adr_i), .wb_dat_o (flash_wb_dat_o), @@ -298,7 +303,9 @@ always_comb begin : memory_mapping flash_wb_stb_i = core_wb_stb_o; end -assign flash_cs_n = ~flash_cs; +assign rst = !pll_locked; + +assign flash_cs_n = !flash_cs; assign sram_ce_n = 1; assign sdram0_cs_n = 1; diff --git a/src/poweron_reset.sv b/src/poweron_reset.sv deleted file mode 100644 index bafe8aa..0000000 --- a/src/poweron_reset.sv +++ /dev/null @@ -1,42 +0,0 @@ -/* __ _ - * ________/ / ___ _(_)__ ___ - * / __/ __/ _ \/ _ `/ / _ \/ -_) - * \__/\__/_//_/\_,_/_/_//_/\__/ - * - * Copyright (C) Clément Chaine - * This file is part of ECAP5-DSOC - * - * ECAP5-DSOC is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ECAP5-DSOC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ECAP5-DSOC. If not, see . - */ - -module poweron_reset ( - input logic clk_i, - output logic rst_o -); - -logic[15:0] counter = '0; -logic rst_internal = 1; - -always_ff @(posedge clk_i) begin - if (counter != '1) begin - counter <= counter + 1'b1; - rst_internal <= 1'b1; - end else begin - rst_internal <= 1'b0; - end -end - -assign rst_o = rst_internal; - -endmodule // poweron_reset diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 134ce8f..4f13b16 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -32,10 +32,36 @@ add_lint_target( LIB ecap5_dsoc ) +# Generate a mocked pll +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generated_pll.v + "module generated_pll(\n" + " input clkin,\n" + " output clkout0,\n" + " output locked\n" + ");\n" + "logic locked_q = 1'b0;\n" + "logic locked_qq;\n" + "always_ff @(posedge clkin) begin\n" + " locked_q <= 1;\n" + " locked_qq <= locked_q;\n" + "end\n" + "assign clkout0 = clkin;\n" + "assign locked = locked_qq;\n" + "endmodule\n" +) +# Create a test interface library +add_library(ecap5_dsoc_tests INTERFACE) +target_sources(ecap5_dsoc_tests INTERFACE + ${CMAKE_CURRENT_BINARY_DIR}/generated_pll.v +) +target_link_libraries(ecap5_dsoc_tests INTERFACE + ecap5_dsoc +) + # Add testbenches add_testbench( MODULE ecap5_dsoc - LIBS ecap5_dsoc + LIBS ecap5_dsoc_tests BENCH_DIR ${BENCH_DIR} TESTDATA_DIR ${TESTDATA_DIR} TEST_INCLUDE_DIRS ${TEST_INCLUDE_DIRS} diff --git a/tests/benches/ecap5_dsoc/tb_ecap5_dsoc.cpp b/tests/benches/ecap5_dsoc/tb_ecap5_dsoc.cpp index 180ef8c..e11325b 100644 --- a/tests/benches/ecap5_dsoc/tb_ecap5_dsoc.cpp +++ b/tests/benches/ecap5_dsoc/tb_ecap5_dsoc.cpp @@ -62,13 +62,15 @@ int main(int argc, char ** argv, char ** env) { tb->init_conditions(__CondIdEnd); tb->debug_log = true; - // 24MHz - tb->clk_period_in_ps = 41667; + // 60MHz + tb->clk_ptr = &tb->core->ext_clk_i; + tb->clk_period_in_ps = 16667; /************************************************************/ tb->reset(); - tb->n_tick(200000); + // 10ms + tb->n_tick(600000); /************************************************************/ diff --git a/tests/benches/ecap5_dsoc/tb_ecap5_dsoc.sv b/tests/benches/ecap5_dsoc/tb_ecap5_dsoc.sv index af816e3..7561ba4 100644 --- a/tests/benches/ecap5_dsoc/tb_ecap5_dsoc.sv +++ b/tests/benches/ecap5_dsoc/tb_ecap5_dsoc.sv @@ -21,7 +21,7 @@ */ module tb_ecap5_dsoc ( - input logic clk_i, + input logic ext_clk_i, //================================= // UART interface @@ -50,7 +50,7 @@ module tb_ecap5_dsoc ( ); ecap5_dsoc dut ( - .clk_i (clk_i), + .ext_clk_i (ext_clk_i), .uart_tx_o (uart_tx_o), .uart_rx_i (uart_rx_i),