2022-09-19 02:51:11 -04:00
|
|
|
//======================================================================
|
|
|
|
//
|
|
|
|
// timer.v
|
|
|
|
// --------
|
|
|
|
// Top level wrapper for the timer core.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Author: Joachim Strombergson
|
|
|
|
// Copyright (C) 2022 - Tillitis AB
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
//
|
|
|
|
//======================================================================
|
|
|
|
|
|
|
|
`default_nettype none
|
|
|
|
|
|
|
|
module timer(
|
|
|
|
input wire clk,
|
|
|
|
input wire reset_n,
|
|
|
|
|
|
|
|
input wire cs,
|
|
|
|
input wire we,
|
|
|
|
|
|
|
|
input wire [7 : 0] address,
|
|
|
|
input wire [31 : 0] write_data,
|
|
|
|
output wire [31 : 0] read_data,
|
|
|
|
output wire ready
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
// Internal constant and parameter definitions.
|
|
|
|
//----------------------------------------------------------------
|
2023-01-23 07:47:04 -05:00
|
|
|
localparam ADDR_CTRL = 8'h08;
|
|
|
|
localparam CTRL_START_BIT = 0;
|
|
|
|
localparam CTRL_STOP_BIT = 1;
|
2022-09-19 02:51:11 -04:00
|
|
|
|
2023-01-23 07:47:04 -05:00
|
|
|
localparam ADDR_STATUS = 8'h09;
|
|
|
|
localparam STATUS_RUNNING_BIT = 0;
|
2022-09-19 02:51:11 -04:00
|
|
|
|
2023-01-23 07:47:04 -05:00
|
|
|
localparam ADDR_PRESCALER = 8'h0a;
|
|
|
|
localparam ADDR_TIMER = 8'h0b;
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
// Registers including update variables and write enable.
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
reg [31 : 0] prescaler_reg;
|
|
|
|
reg prescaler_we;
|
|
|
|
|
|
|
|
reg [31 : 0] timer_reg;
|
|
|
|
reg timer_we;
|
|
|
|
|
2023-01-23 07:47:04 -05:00
|
|
|
reg start_reg;
|
|
|
|
reg start_new;
|
|
|
|
|
|
|
|
reg stop_reg;
|
|
|
|
reg stop_new;
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
// Wires.
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
reg [31 : 0] tmp_read_data;
|
|
|
|
reg tmp_ready;
|
|
|
|
|
2023-01-23 07:47:04 -05:00
|
|
|
wire core_running;
|
2022-09-19 02:51:11 -04:00
|
|
|
wire [31 : 0] core_curr_timer;
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
// Concurrent connectivity for ports etc.
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
assign read_data = tmp_read_data;
|
2023-01-23 07:47:04 -05:00
|
|
|
assign ready = tmp_ready;
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
// core instantiation.
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
timer_core core(
|
|
|
|
.clk(clk),
|
|
|
|
.reset_n(reset_n),
|
2022-10-13 10:10:08 -04:00
|
|
|
|
2022-10-13 08:58:39 -04:00
|
|
|
.prescaler_init(prescaler_reg),
|
|
|
|
.timer_init(timer_reg),
|
2023-01-23 07:47:04 -05:00
|
|
|
.start(start_reg),
|
|
|
|
.stop(stop_reg),
|
2022-10-13 10:10:08 -04:00
|
|
|
|
2022-09-19 02:51:11 -04:00
|
|
|
.curr_timer(core_curr_timer),
|
2023-01-23 07:47:04 -05:00
|
|
|
.running(core_running)
|
2022-09-19 02:51:11 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
// reg_update
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
always @ (posedge clk)
|
|
|
|
begin : reg_update
|
|
|
|
if (!reset_n) begin
|
2023-01-23 07:47:04 -05:00
|
|
|
start_reg <= 1'h0;
|
|
|
|
stop_reg <= 1'h0;
|
|
|
|
prescaler_reg <= 32'h0;
|
|
|
|
timer_reg <= 32'h0;
|
2022-09-19 02:51:11 -04:00
|
|
|
end
|
|
|
|
else begin
|
2023-01-23 07:47:04 -05:00
|
|
|
start_reg <= start_new;
|
|
|
|
stop_reg <= stop_new;
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
if (prescaler_we) begin
|
|
|
|
prescaler_reg <= write_data;
|
|
|
|
end
|
|
|
|
|
|
|
|
if (timer_we) begin
|
|
|
|
timer_reg <= write_data;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end // reg_update
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
// api
|
|
|
|
//
|
|
|
|
// The interface command decoding logic.
|
|
|
|
//----------------------------------------------------------------
|
|
|
|
always @*
|
|
|
|
begin : api
|
2023-01-23 07:47:04 -05:00
|
|
|
start_new = 1'h0;
|
|
|
|
stop_new = 1'h0;
|
|
|
|
prescaler_we = 1'h0;
|
|
|
|
timer_we = 1'h0;
|
|
|
|
tmp_read_data = 32'h0;
|
|
|
|
tmp_ready = 1'h0;
|
2022-09-19 02:51:11 -04:00
|
|
|
|
|
|
|
if (cs) begin
|
|
|
|
tmp_ready = 1'h1;
|
|
|
|
|
|
|
|
if (we) begin
|
|
|
|
if (address == ADDR_CTRL) begin
|
2023-01-23 07:47:04 -05:00
|
|
|
start_new = write_data[CTRL_START_BIT];
|
|
|
|
stop_new = write_data[CTRL_STOP_BIT];
|
2022-09-19 02:51:11 -04:00
|
|
|
end
|
|
|
|
|
2023-01-23 07:47:04 -05:00
|
|
|
if (!core_running) begin
|
2022-09-19 02:51:11 -04:00
|
|
|
if (address == ADDR_PRESCALER) begin
|
|
|
|
prescaler_we = 1'h1;
|
|
|
|
end
|
|
|
|
|
|
|
|
if (address == ADDR_TIMER) begin
|
|
|
|
timer_we = 1'h1;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
else begin
|
|
|
|
if (address == ADDR_STATUS) begin
|
2023-01-23 07:47:04 -05:00
|
|
|
tmp_read_data[STATUS_RUNNING_BIT] = core_running;
|
2022-09-19 02:51:11 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
if (address == ADDR_PRESCALER) begin
|
2022-10-06 09:56:13 -04:00
|
|
|
tmp_read_data = prescaler_reg;
|
2022-09-19 02:51:11 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
if (address == ADDR_TIMER) begin
|
2023-01-23 07:47:04 -05:00
|
|
|
if (!core_running) begin
|
2022-10-13 08:58:39 -04:00
|
|
|
tmp_read_data = timer_reg;
|
2023-01-23 07:47:04 -05:00
|
|
|
end
|
|
|
|
else begin
|
2022-10-13 08:58:39 -04:00
|
|
|
tmp_read_data = core_curr_timer;
|
|
|
|
end
|
2022-09-19 02:51:11 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end // addr_decoder
|
|
|
|
endmodule // timer
|
|
|
|
|
|
|
|
//======================================================================
|
|
|
|
// EOF timer.v
|
|
|
|
//======================================================================
|