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),