Add RISC-V timer to example soc, and tweak ULX3S config
This commit is contained in:
parent
a18c3018e1
commit
8721bd3deb
|
@ -62,6 +62,7 @@ activity_led #(
|
||||||
);
|
);
|
||||||
|
|
||||||
example_soc #(
|
example_soc #(
|
||||||
|
.CLK_MHZ (12),
|
||||||
.EXTENSION_A (1),
|
.EXTENSION_A (1),
|
||||||
.EXTENSION_C (0),
|
.EXTENSION_C (0),
|
||||||
.EXTENSION_M (1),
|
.EXTENSION_M (1),
|
||||||
|
@ -72,6 +73,7 @@ example_soc #(
|
||||||
.EXTENSION_ZBKB (0),
|
.EXTENSION_ZBKB (0),
|
||||||
.EXTENSION_ZIFENCEI (0),
|
.EXTENSION_ZIFENCEI (0),
|
||||||
.EXTENSION_XH3BEXTM (0),
|
.EXTENSION_XH3BEXTM (0),
|
||||||
|
.EXTENSION_XH3PMPM (0),
|
||||||
.EXTENSION_XH3POWER (0),
|
.EXTENSION_XH3POWER (0),
|
||||||
.CSR_COUNTER (0),
|
.CSR_COUNTER (0),
|
||||||
.U_MODE (0),
|
.U_MODE (0),
|
||||||
|
|
|
@ -17,7 +17,7 @@ wire clk_sys;
|
||||||
wire pll_sys_locked;
|
wire pll_sys_locked;
|
||||||
wire rst_n_sys;
|
wire rst_n_sys;
|
||||||
|
|
||||||
pll_25_40 pll_sys (
|
pll_25_50 pll_sys (
|
||||||
.clkin (clk_osc),
|
.clkin (clk_osc),
|
||||||
.clkout0 (clk_sys),
|
.clkout0 (clk_sys),
|
||||||
.locked (pll_sys_locked)
|
.locked (pll_sys_locked)
|
||||||
|
@ -32,19 +32,29 @@ fpga_reset #(
|
||||||
);
|
);
|
||||||
|
|
||||||
example_soc #(
|
example_soc #(
|
||||||
.DTM_TYPE ("ECP5"),
|
.DTM_TYPE ("ECP5"),
|
||||||
.SRAM_DEPTH (1 << 15),
|
.SRAM_DEPTH (1 << 15),
|
||||||
|
.CLK_MHZ (50),
|
||||||
|
|
||||||
.EXTENSION_M (1),
|
.EXTENSION_M (1),
|
||||||
.EXTENSION_A (1),
|
.EXTENSION_A (1),
|
||||||
.EXTENSION_C (0),
|
.EXTENSION_C (0),
|
||||||
.EXTENSION_ZBA (0),
|
.EXTENSION_ZBA (0),
|
||||||
.EXTENSION_ZBB (0),
|
.EXTENSION_ZBB (0),
|
||||||
.EXTENSION_ZBC (0),
|
.EXTENSION_ZBC (0),
|
||||||
.EXTENSION_ZBS (0),
|
.EXTENSION_ZBS (0),
|
||||||
.CSR_COUNTER (0),
|
.EXTENSION_ZBKB (0),
|
||||||
.MUL_FAST (1),
|
.EXTENSION_ZIFENCEI (1),
|
||||||
.MULDIV_UNROLL (1)
|
.EXTENSION_XH3BEXTM (0),
|
||||||
|
.EXTENSION_XH3PMPM (0),
|
||||||
|
.EXTENSION_XH3POWER (0),
|
||||||
|
.CSR_COUNTER (1),
|
||||||
|
.MUL_FAST (1),
|
||||||
|
.MUL_FASTER (0),
|
||||||
|
.MULH_FAST (0),
|
||||||
|
.MULDIV_UNROLL (1),
|
||||||
|
.FAST_BRANCHCMP (1),
|
||||||
|
.BRANCH_PREDICTOR (1)
|
||||||
) soc_u (
|
) soc_u (
|
||||||
.clk (clk_sys),
|
.clk (clk_sys),
|
||||||
.rst_n (rst_n_sys),
|
.rst_n (rst_n_sys),
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
`default_nettype none
|
`default_nettype none
|
||||||
|
|
||||||
module example_soc #(
|
module example_soc #(
|
||||||
parameter DTM_TYPE = "JTAG", // can be "JTAG" or "ECP5"
|
parameter DTM_TYPE = "JTAG", // Can be "JTAG" or "ECP5"
|
||||||
parameter SRAM_DEPTH = 1 << 15, // default 32 kwords -> 128 kB
|
parameter SRAM_DEPTH = 1 << 15, // Default 32 kwords -> 128 kB
|
||||||
|
parameter CLK_MHZ = 12, // For timer timebase
|
||||||
|
|
||||||
`include "hazard3_config.vh"
|
`include "hazard3_config.vh"
|
||||||
) (
|
) (
|
||||||
|
@ -262,6 +263,8 @@ hazard3_cpu_1port #(
|
||||||
.EXTENSION_ZBKB (EXTENSION_ZBKB),
|
.EXTENSION_ZBKB (EXTENSION_ZBKB),
|
||||||
.EXTENSION_ZIFENCEI (EXTENSION_ZIFENCEI),
|
.EXTENSION_ZIFENCEI (EXTENSION_ZIFENCEI),
|
||||||
.EXTENSION_XH3BEXTM (EXTENSION_XH3BEXTM),
|
.EXTENSION_XH3BEXTM (EXTENSION_XH3BEXTM),
|
||||||
|
.EXTENSION_XH3IRQ (EXTENSION_XH3IRQ),
|
||||||
|
.EXTENSION_XH3PMPM (EXTENSION_XH3PMPM),
|
||||||
.EXTENSION_XH3POWER (EXTENSION_XH3POWER),
|
.EXTENSION_XH3POWER (EXTENSION_XH3POWER),
|
||||||
.CSR_COUNTER (CSR_COUNTER),
|
.CSR_COUNTER (CSR_COUNTER),
|
||||||
.U_MODE (U_MODE),
|
.U_MODE (U_MODE),
|
||||||
|
@ -538,30 +541,43 @@ uart_mini uart_u (
|
||||||
.dreq (/* unused */)
|
.dreq (/* unused */)
|
||||||
);
|
);
|
||||||
|
|
||||||
// hazard3_riscv_timer timer_u (
|
// Microsecond timebase for timer
|
||||||
// .clk (clk),
|
|
||||||
// .rst_n (rst_n),
|
|
||||||
|
|
||||||
// .psel (timer_psel),
|
reg [$clog2(CLK_MHZ)-1:0] timer_tick_ctr;
|
||||||
// .penable (timer_penable),
|
reg timer_tick;
|
||||||
// .pwrite (timer_pwrite),
|
|
||||||
// .paddr (timer_paddr),
|
|
||||||
// .pwdata (timer_pwdata),
|
|
||||||
// .prdata (timer_prdata),
|
|
||||||
// .pready (timer_pready),
|
|
||||||
// .pslverr (timer_pslverr),
|
|
||||||
|
|
||||||
// .dbg_halt (&hart_halted),
|
always @ (posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
timer_tick_ctr <= {$clog2(CLK_MHZ){1'b0}};
|
||||||
|
timer_tick <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
if (|timer_tick_ctr) begin
|
||||||
|
timer_tick_ctr <= timer_tick_ctr - 1'b1;
|
||||||
|
end else begin
|
||||||
|
timer_tick_ctr <= CLK_MHZ - 1;
|
||||||
|
end
|
||||||
|
timer_tick <= ~|timer_tick_ctr;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
// // Tie high for 64-cycle timebase:
|
hazard3_riscv_timer timer_u (
|
||||||
// .tick (1'b1),
|
.clk (clk),
|
||||||
|
.rst_n (rst_n),
|
||||||
|
|
||||||
// .timer_irq (timer_irq)
|
.psel (timer_psel),
|
||||||
// );
|
.penable (timer_penable),
|
||||||
|
.pwrite (timer_pwrite),
|
||||||
|
.paddr (timer_paddr),
|
||||||
|
.pwdata (timer_pwdata),
|
||||||
|
.prdata (timer_prdata),
|
||||||
|
.pready (timer_pready),
|
||||||
|
.pslverr (timer_pslverr),
|
||||||
|
|
||||||
assign timer_pslverr = 1'b0;
|
.dbg_halt (&hart_halted),
|
||||||
assign timer_pready = 1'b1;
|
|
||||||
assign timer_prdata = 32'h0;
|
.tick (timer_tick),
|
||||||
assign timer_irq = 1'b0;
|
|
||||||
|
.timer_irq (timer_irq)
|
||||||
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
file hazard3_riscv_timer.v
|
||||||
|
file ../../../hdl/debug/cdc/hazard3_sync_1bit.v
|
|
@ -0,0 +1,142 @@
|
||||||
|
/*****************************************************************************\
|
||||||
|
| Copyright (C) 2022 Luke Wren |
|
||||||
|
| SPDX-License-Identifier: Apache-2.0 |
|
||||||
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
`default_nettype none
|
||||||
|
|
||||||
|
// Basic implementation of standard 64-bit RISC-V timer with 32-bit APB.
|
||||||
|
|
||||||
|
// TICK_IS_NRZ = 1: tick is an NRZ signal that is asynchronous to clk.
|
||||||
|
// TICK_IS_NRZ = 0: tick is a level-sensitive signal that is synchronous to clk.
|
||||||
|
|
||||||
|
module hazard3_riscv_timer #(
|
||||||
|
parameter TICK_IS_NRZ = 0
|
||||||
|
) (
|
||||||
|
input wire clk,
|
||||||
|
input wire rst_n,
|
||||||
|
|
||||||
|
input wire [15:0] paddr,
|
||||||
|
input wire psel,
|
||||||
|
input wire penable,
|
||||||
|
input wire pwrite,
|
||||||
|
input wire [31:0] pwdata,
|
||||||
|
output reg [31:0] prdata,
|
||||||
|
output wire pready,
|
||||||
|
output wire pslverr,
|
||||||
|
|
||||||
|
input wire dbg_halt,
|
||||||
|
input wire tick,
|
||||||
|
|
||||||
|
output reg timer_irq
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam ADDR_CTRL = 16'h0000;
|
||||||
|
localparam ADDR_MTIME = 16'h0008;
|
||||||
|
localparam ADDR_MTIMEH = 16'h000c;
|
||||||
|
localparam ADDR_MTIMECMP = 16'h0010;
|
||||||
|
localparam ADDR_MTIMECMPH = 16'h0014;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Timer tick logic
|
||||||
|
|
||||||
|
wire tick_event;
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (TICK_IS_NRZ) begin: edge_detect
|
||||||
|
|
||||||
|
wire tick_nrz_sync;
|
||||||
|
|
||||||
|
hazard3_sync_1bit tick_sync_u (
|
||||||
|
.clk (clk),
|
||||||
|
.rst_n (rst_n),
|
||||||
|
.i (tick_nrz),
|
||||||
|
.o (tick_nrz_sync)
|
||||||
|
);
|
||||||
|
|
||||||
|
reg tick_nrz_prev;
|
||||||
|
always @ (posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
tick_nrz_prev <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
tick_nrz_prev <= tick_nrz_sync;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assign tick_event = tick_nrz_sync ^ tick_nrz_sync_prev;
|
||||||
|
|
||||||
|
end else begin: no_edge_detect
|
||||||
|
|
||||||
|
assign tick_event = tick;
|
||||||
|
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
reg ctrl_en;
|
||||||
|
wire tick_now = tick_event && ctrl_en && !dbg_halt;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Counter registers
|
||||||
|
|
||||||
|
wire bus_write = pwrite && psel && penable;
|
||||||
|
wire bus_read = !pwrite && psel && penable;
|
||||||
|
|
||||||
|
always @ (posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
ctrl_en <= 1'b1;
|
||||||
|
end else if (bus_write && paddr == ADDR_CTRL) begin
|
||||||
|
ctrl_en <= pwdata[0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
reg [63:0] mtime;
|
||||||
|
|
||||||
|
always @ (posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
mtime <= 64'h0;
|
||||||
|
end else begin
|
||||||
|
if (tick_now)
|
||||||
|
mtime <= mtime + 1'b1;
|
||||||
|
if (bus_write && paddr == ADDR_MTIME)
|
||||||
|
mtime[31:0] <= pwdata;
|
||||||
|
if (bus_write && paddr == ADDR_MTIMEH)
|
||||||
|
mtime[63:32] <= pwdata;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// mtimecmp is stored inverted for minor LUT savings on iCE40
|
||||||
|
reg [63:0] mtimecmp;
|
||||||
|
wire [64:0] cmp_diff = {1'b0, mtime} + {1'b0, mtimecmp} + 65'd1;
|
||||||
|
|
||||||
|
always @ (posedge clk or negedge rst_n) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
mtimecmp <= 64'h0;
|
||||||
|
timer_irq <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
if (bus_write && paddr == ADDR_MTIMECMP)
|
||||||
|
mtimecmp[31:0] <= ~pwdata;
|
||||||
|
if (bus_write && paddr == ADDR_MTIMECMPH)
|
||||||
|
mtimecmp[63:32] <= ~pwdata;
|
||||||
|
timer_irq <= cmp_diff[64];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @ (*) begin
|
||||||
|
case (paddr)
|
||||||
|
ADDR_CTRL: prdata = {31'h0, ctrl_en};
|
||||||
|
ADDR_MTIME: prdata = mtime[31:0];
|
||||||
|
ADDR_MTIMEH: prdata = mtime[63:32];
|
||||||
|
ADDR_MTIMECMP: prdata = ~mtimecmp[31:0];
|
||||||
|
ADDR_MTIMECMPH: prdata = ~mtimecmp[63:32];
|
||||||
|
default: prdata = 32'h0;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
assign pready = 1'b1;
|
||||||
|
assign pslverr = 1'b0;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`ifndef YOSYS
|
||||||
|
`default_nettype none
|
||||||
|
`endif
|
|
@ -8,6 +8,10 @@ list $HDL/hazard3.f
|
||||||
list $HDL/debug/dtm/hazard3_jtag_dtm.f
|
list $HDL/debug/dtm/hazard3_jtag_dtm.f
|
||||||
list $HDL/debug/dm/hazard3_dm.f
|
list $HDL/debug/dm/hazard3_dm.f
|
||||||
|
|
||||||
|
# RISC-V timer
|
||||||
|
|
||||||
|
list peri/hazard3_riscv_timer.f
|
||||||
|
|
||||||
# Generic SoC components from libfpga
|
# Generic SoC components from libfpga
|
||||||
|
|
||||||
file ../libfpga/common/reset_sync.v
|
file ../libfpga/common/reset_sync.v
|
||||||
|
|
Loading…
Reference in New Issue