Skip to content

Commit

Permalink
hsoc: add timer
Browse files Browse the repository at this point in the history
  • Loading branch information
saursin committed Oct 29, 2023
1 parent b27188e commit a6e00f4
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 4 deletions.
48 changes: 44 additions & 4 deletions rtl/soc/hydrogensoc/HydrogenSoC.v
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ module HydrogenSoC(
`ifdef EN_EXCEPT
,
.irq_i (1'b0),
.timer_int_i (1'b0)
.timer_int_i (timer_int_o)
`endif // EN_EXCEPT
);

Expand Down Expand Up @@ -182,7 +182,7 @@ module HydrogenSoC(


// ******************** Crossbar ********************
Crossbar5_wb #(
Crossbar6_wb #(
.DATA_WIDTH (32),
.ADDR_WIDTH (32),
.DEVICE0_ADDR (`BOOTROM_ADDR),
Expand All @@ -194,7 +194,9 @@ module HydrogenSoC(
.DEVICE3_ADDR (`GPIO_ADDR),
.DEVICE3_MASK (`size_to_mask32(`GPIO_SIZE)),
.DEVICE4_ADDR (`SPI_ADDR),
.DEVICE4_MASK (`size_to_mask32(`SPI_SIZE))
.DEVICE4_MASK (`size_to_mask32(`SPI_SIZE)),
.DEVICE5_ADDR (`TIMER_ADDR),
.DEVICE5_MASK (`size_to_mask32(`TIMER_SIZE))
) xbar (
.wbs_adr_i (arb_wb_adr_o),
.wbs_dat_i (arb_wb_dat_o),
Expand Down Expand Up @@ -256,7 +258,17 @@ module HydrogenSoC(
.wbm4_cyc_o (spi_wb_cyc_i),
.wbm4_stb_o (spi_wb_stb_i),
.wbm4_ack_i (spi_wb_ack_o),
.wbm4_err_i (1'b0)
.wbm4_err_i (1'b0),

.wbm5_adr_o (timer_wb_adr_i),
.wbm5_dat_i (timer_wb_dat_o),
.wbm5_dat_o (timer_wb_dat_i),
.wbm5_we_o (timer_wb_we_i),
.wbm5_sel_o (timer_wb_sel_i),
.wbm5_cyc_o (timer_wb_cyc_i),
.wbm5_stb_o (timer_wb_stb_i),
.wbm5_ack_i (timer_wb_ack_o),
.wbm5_err_i (1'b0)
);


Expand Down Expand Up @@ -410,6 +422,34 @@ module HydrogenSoC(
.miso_i (spi_miso_i),
.mosi_o (spi_mosi_o),
.cs_o (spi_cs_o)
);

// ******************* TIMER *******************
/* verilator lint_off UNUSEDSIGNAL */
wire [31:0] timer_wb_adr_i;
/* verilator lint_on UNUSEDSIGNAL */
wire [31:0] timer_wb_dat_o;
wire [31:0] timer_wb_dat_i;
wire timer_wb_we_i;
wire [3:0] timer_wb_sel_i;
wire timer_wb_cyc_i;
wire timer_wb_stb_i;
wire timer_wb_ack_o;
wire timer_int_o;

Timer_wb timer (
.wb_clk_i (wb_clk_i),
.wb_rst_i (wb_rst_i),

.wb_adr_i (timer_wb_adr_i[3:2]),
.wb_dat_o (timer_wb_dat_o),
.wb_dat_i (timer_wb_dat_i),
.wb_we_i (timer_wb_we_i),
.wb_sel_i (timer_wb_sel_i),
.wb_stb_i (timer_wb_stb_i & timer_wb_cyc_i),
.wb_ack_o (timer_wb_ack_o),

.int_o (timer_int_o)
);


Expand Down
4 changes: 4 additions & 0 deletions rtl/soc/hydrogensoc/HydrogenSoC_Config.vh
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,9 @@
`define SPI_ADDR 32'h4000_3000
`define SPI_SIZE 32 // 32 bytes (8 words)

// TIMER
`define TIMER_ADDR 32'h4000_4000
`define TIMER_SIZE 16 // 32 bytes (4 words)


`endif // __HYDROGENSOC_CONFIG_VH__
21 changes: 21 additions & 0 deletions rtl/uncore/timer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Wishbone Timer
Timer IP with Wishbone B-4 Interface.

## Register MAP

| **Offset** | **Name** | **Description**
|------------|------------|-----------------------------------
| 0x00 | MTIME | Machine mode time register [31:0]
| 0x04 | MTIME_H | Machine mode time register [63:32]
| 0x08 | MTIMECMP | Machine mode time compare register [31:0]
| 0x0c | MTIMECMP_H | Machine mode time compare register [63:32]

> Timer interrupt (`mti`) is generated whenever `mtimecmp` >= `mtime`. The `mti` interrupt does not repeat, so the ISR needs to reset the timer compare register (`mtimecmp`) at each timeout.
## Logic Utilization
Yosys was used to analyze Logic utilization for Xilinx 7 series FPGAs

| **Design** | **LUTS** |
|---------------|----------|
| SPI_core | 322 |
| SPI_wb | 530 |
104 changes: 104 additions & 0 deletions rtl/uncore/timer/Timer_wb.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
////////////////////////////////////////////////////////////////////
// File : GPIO.v
// Author : Saurabh Singh ([email protected])
// Description : GPIO IP with Wishbone B-4 Interface.
//
// MIT License
//
// Copyright (c) 2021 Saurabh Singh
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
////////////////////////////////////////////////////////////////////

`default_nettype none
`include "Utils.vh"

module Timer_wb(
// Wishbone Interface
input wire wb_clk_i,
input wire wb_rst_i,

input wire [3:2] wb_adr_i,
output reg [31:0] wb_dat_o,
input wire [31:0] wb_dat_i,
input wire wb_we_i,
input wire [3:0] wb_sel_i,
input wire wb_stb_i,
output reg wb_ack_o,

output wire int_o
);

// Set Ack_o
always @(posedge wb_clk_i) begin
if (wb_rst_i)
wb_ack_o <= 1'b0;
else
wb_ack_o <= wb_stb_i & !wb_ack_o;
end

wire [3:0] we = {4{wb_we_i & wb_stb_i}} & wb_sel_i;


reg [63:0] mtime;
reg [63:0] mtimecmp;

assign int_o = mtime >= mtimecmp;

// Writes
always @(posedge wb_clk_i) begin
if(wb_rst_i) begin
mtime <= 'd0;
mtimecmp <= 'd0;
end
else begin
case(wb_adr_i)
2'b10: begin // mtimecmp
if (we[0]) mtimecmp[7:0] <= wb_dat_i[7:0];
if (we[1]) mtimecmp[15:8] <= wb_dat_i[15:8];
if (we[2]) mtimecmp[23:16] <= wb_dat_i[23:16];
if (we[3]) mtimecmp[31:24] <= wb_dat_i[31:24];
end
2'b11: begin // mtimecmp_h
if (we[0]) mtimecmp[39:32] <= wb_dat_i[7:0];
if (we[1]) mtimecmp[47:40] <= wb_dat_i[15:8];
if (we[2]) mtimecmp[55:48] <= wb_dat_i[23:16];
if (we[3]) mtimecmp[63:56] <= wb_dat_i[31:24];
end
default: begin // INC (NOT IMPLEMENTED)
end
endcase
mtime <= mtime + 'd1;
end
end


// READS
always @(*) /* COMBINATORIAL */ begin
case(wb_adr_i)
2'b00: /* mtime */ wb_dat_o = mtime[31:0];
2'b01: /* mtime_h */ wb_dat_o = mtime[63:32];
2'b10: /* mtimecmp */ wb_dat_o = mtimecmp[31:0];
2'b11: /* mtimecmp_h */ wb_dat_o = mtimecmp[63:32];
default:
wb_dat_o = 'dx;
endcase
end

endmodule

0 comments on commit a6e00f4

Please sign in to comment.