(fpga) Make free running the only timer mode

Change timer from counting to a specified value and stopping or
       free running, to always be free running. But now the timer sets
       a reached flag when the target number of ticks has been
       reached.

Signed-off-by: Joachim Strömbergson <joachim@assured.se>
This commit is contained in:
Joachim Strömbergson 2024-08-21 13:35:49 +02:00
parent bffe2eca02
commit eb00b4e2e9
No known key found for this signature in database
GPG Key ID: 865B8A548EA61679
4 changed files with 43 additions and 42 deletions

View File

@ -36,11 +36,10 @@ module timer(
localparam ADDR_STATUS = 8'h09;
localparam STATUS_RUNNING_BIT = 0;
localparam STATUS_REACHED_BIT = 1;
localparam ADDR_PRESCALER = 8'h0a;
localparam ADDR_TIMER = 8'h0b;
localparam ADDR_FREE_RUNNING = 8'h0c;
localparam FREE_RUNNING_BIT = 0;
//----------------------------------------------------------------
@ -58,9 +57,6 @@ module timer(
reg stop_reg;
reg stop_new;
reg free_running_reg;
reg free_running_we;
//----------------------------------------------------------------
// Wires.
@ -68,8 +64,9 @@ module timer(
reg [31 : 0] tmp_read_data;
reg tmp_ready;
wire core_running;
wire [31 : 0] core_curr_timer;
wire core_reached;
wire core_running;
//----------------------------------------------------------------
@ -90,9 +87,9 @@ module timer(
.timer_init(timer_reg),
.start(start_reg),
.stop(stop_reg),
.free_running(free_running_reg),
.curr_timer(core_curr_timer),
.reached(core_reached),
.running(core_running)
);
@ -105,7 +102,6 @@ module timer(
if (!reset_n) begin
start_reg <= 1'h0;
stop_reg <= 1'h0;
free_running_reg <= 1'h0;
prescaler_reg <= 32'h1;
timer_reg <= 32'h1;
end
@ -120,10 +116,6 @@ module timer(
if (timer_we) begin
timer_reg <= write_data;
end
if (free_running_we) begin
free_running_reg <= write_data[FREE_RUNNING_BIT];
end
end
end // reg_update
@ -137,7 +129,6 @@ module timer(
begin : api
start_new = 1'h0;
stop_new = 1'h0;
free_running_we = 1'h0;
prescaler_we = 1'h0;
timer_we = 1'h0;
tmp_read_data = 32'h0;
@ -160,16 +151,12 @@ module timer(
if (address == ADDR_TIMER) begin
timer_we = 1'h1;
end
if (address == ADDR_FREE_RUNNING) begin
free_running_we = 1'h1;
end
end
end
end
end
else begin
if (address == ADDR_STATUS) begin
tmp_read_data[STATUS_RUNNING_BIT] = core_running;
tmp_read_data[1 : 0] = {core_reached, core_running};
end
if (address == ADDR_PRESCALER) begin

View File

@ -21,9 +21,9 @@ module timer_core(
input wire [31 : 0] timer_init,
input wire start,
input wire stop,
input wire free_running,
output wire [31 : 0] curr_timer,
output wire reached,
output wire running
);
@ -42,6 +42,10 @@ module timer_core(
reg running_new;
reg running_we;
reg reached_reg;
reg reached_new;
reg reached_we;
reg [31 : 0] prescaler_reg;
reg [31 : 0] prescaler_new;
reg prescaler_we;
@ -63,6 +67,7 @@ module timer_core(
// Concurrent connectivity for ports etc.
//----------------------------------------------------------------
assign curr_timer = timer_reg;
assign reached = reached_reg;
assign running = running_reg;
@ -73,6 +78,7 @@ module timer_core(
begin: reg_update
if (!reset_n)
begin
reached_reg <= 1'h0;
running_reg <= 1'h0;
prescaler_reg <= 32'h0;
timer_reg <= 32'h0;
@ -80,6 +86,9 @@ module timer_core(
end
else
begin
if (reached_we) begin
reached_reg <= reached_new;
end
if (running_we) begin
running_reg <= running_new;
end
@ -142,6 +151,8 @@ module timer_core(
//----------------------------------------------------------------
always @*
begin : core_ctrl
reached_new = 1'h0;
reached_we = 1'h0;
running_new = 1'h0;
running_we = 1'h0;
prescaler_rst = 1'h0;
@ -158,7 +169,6 @@ module timer_core(
running_we = 1'h1;
prescaler_rst = 1'h1;
timer_rst = 1'h1;
core_ctrl_new = CTRL_RUNNING;
core_ctrl_we = 1'h1;
end
@ -167,6 +177,8 @@ module timer_core(
CTRL_RUNNING: begin
if (stop) begin
reached_new = 1'h0;
reached_we = 1'h1;
running_new = 1'h0;
running_we = 1'h1;
core_ctrl_new = CTRL_IDLE;
@ -175,16 +187,12 @@ module timer_core(
else begin
if (prescaler_reg == (prescaler_init - 1)) begin
if ((timer_reg == (timer_init - 1)) & ~free_running) begin
running_new = 1'h0;
running_we = 1'h1;
core_ctrl_new = CTRL_IDLE;
core_ctrl_we = 1'h1;
end
else begin
timer_inc = 1'h1;
prescaler_rst = 1'h1;
if (timer_reg == (timer_init - 1)) begin
reached_new = 1'h1;
reached_we = 1'h1;
end
timer_inc = 1'h1;
prescaler_rst = 1'h1;
end
else begin
prescaler_inc = 1'h1;

View File

@ -255,7 +255,7 @@ module tb_timer();
// test1()
//
// Set timer and scaler and then start the timer. Wait
// for the ready flag to be asserted again.
// for the reached flag to be asserted.
//----------------------------------------------------------------
task test1;
begin : test1
@ -275,12 +275,13 @@ module tb_timer();
write_word(ADDR_TIMER, 32'h9);
time_expected = 32'h6 * 32'h9;
// Start the timer.
write_word(ADDR_CTRL, 32'h1);
time_start = cycle_ctr;
#(CLK_PERIOD);
read_word(ADDR_STATUS);
while (read_data) begin
while (read_data != 3) begin
read_word(ADDR_STATUS);
end
time_stop = cycle_ctr;
@ -296,10 +297,13 @@ module tb_timer();
error_ctr = error_ctr + 1;
end
// Stop the timer.
write_word(ADDR_CTRL, 32'h2);
$display("--- test1: completed.");
$display("");
end
endtask // tes1
endtask // test1
//----------------------------------------------------------------
@ -373,7 +377,7 @@ module tb_timer();
$display("");
$display("--- test3: started.");
$display("--- test3: Free running counter with prescaler in an expected number of cycles.");
$display("--- test3: Free running counter with prescaler = 2 in an expected number of cycles.");
write_word(ADDR_PRESCALER, 32'h2);
write_word(ADDR_TIMER, 32'h9);

View File

@ -39,8 +39,8 @@ module tb_timer_core();
reg [31 : 0] tb_timer_init;
reg tb_start;
reg tb_stop;
reg tb_free_running;
wire [31 : 0] tb_curr_timer;
wire tb_reached;
wire tb_running;
@ -54,8 +54,8 @@ module tb_timer_core();
.timer_init(tb_timer_init),
.start(tb_start),
.stop(tb_stop),
.free_running(tb_free_running),
.curr_timer(tb_curr_timer),
.reached(tb_reached),
.running(tb_running)
);
@ -103,8 +103,8 @@ module tb_timer_core();
$display("Inputs and outputs:");
$display("prescaler_init: 0x%08x, timer_init: 0x%08x",
dut.prescaler_init, dut.timer_init);
$display("start: 0x%1x, stop: 0x%1x, running: 0x%1x",
dut.start, dut.stop, dut.running);
$display("start: 0x%1x, stop: 0x%1x, reached: 0x%1x, running: 0x%1x",
dut.start, dut.stop, dut.reached);
$display("");
$display("Internal state:");
$display("prescaler_reg: 0x%08x, prescaler_new: 0x%08x",
@ -206,7 +206,6 @@ module tb_timer_core();
tb_start = 1'h0;
tb_stop = 1'h0;
tb_free_running = 1'h0;
tb_prescaler_init = 32'h0;
tb_timer_init = 32'h0;
end
@ -239,7 +238,7 @@ module tb_timer_core();
tb_start = 1'h0;
#(CLK_PERIOD);
while (tb_running) begin
while (~tb_reached) begin
#(CLK_PERIOD);
end
test1_counted_num_cycles = cycle_ctr - test1_cycle_ctr_start;
@ -254,6 +253,10 @@ module tb_timer_core();
error_ctr = error_ctr + 1;
end
tb_stop = 1'h1;
#(CLK_PERIOD);
tb_stop = 1'h0;
$display("--- test1: Completed.");
$display("");
end
@ -279,7 +282,6 @@ module tb_timer_core();
tb_prescaler_init = 32'h1;
tb_timer_init = 32'h1;
tb_free_running = 1'h1;
tb_start = 1'h1;
test1_cycle_ctr_start = cycle_ctr;