(fpga) Initial version of support for a free running timer

Add initial version of changes needed to allow the timer to
       optionally be free running.

       This commit changes how the prescaler and timer counts.
       Instead of down from a set value, they count from zero and up
       to a set value.

Signed-off-by: Joachim Strömbergson <joachim@assured.se>
This commit is contained in:
Joachim Strömbergson 2024-08-15 08:32:38 +02:00
parent b5ba21148d
commit 9c465cd813
No known key found for this signature in database
GPG Key ID: 5DDC7C542422EC8D
2 changed files with 35 additions and 44 deletions

View File

@ -21,6 +21,7 @@ module timer_core(
input wire [31 : 0] timer_init, input wire [31 : 0] timer_init,
input wire start, input wire start,
input wire stop, input wire stop,
input wire free_running,
output wire [31 : 0] curr_timer, output wire [31 : 0] curr_timer,
output wire running output wire running
@ -45,14 +46,14 @@ module timer_core(
reg [31 : 0] prescaler_reg; reg [31 : 0] prescaler_reg;
reg [31 : 0] prescaler_new; reg [31 : 0] prescaler_new;
reg prescaler_we; reg prescaler_we;
reg prescaler_set; reg prescaler_rst;
reg prescaler_dec; reg prescaler_inc;
reg [31 : 0] timer_reg; reg [31 : 0] timer_reg;
reg [31 : 0] timer_new; reg [31 : 0] timer_new;
reg timer_we; reg timer_we;
reg timer_set; reg timer_rst;
reg timer_dec; reg timer_inc;
reg [1 : 0] core_ctrl_reg; reg [1 : 0] core_ctrl_reg;
reg [1 : 0] core_ctrl_new; reg [1 : 0] core_ctrl_new;
@ -107,12 +108,12 @@ module timer_core(
prescaler_new = 32'h0; prescaler_new = 32'h0;
prescaler_we = 1'h0; prescaler_we = 1'h0;
if (prescaler_set) begin if (prescaler_rst) begin
prescaler_new = prescaler_init; prescaler_new = 32'h0;
prescaler_we = 1'h1; prescaler_we = 1'h1;
end end
else if (prescaler_dec) begin else if (prescaler_inc) begin
prescaler_new = prescaler_reg - 1'h1; prescaler_new = prescaler_reg + 1'h1;
prescaler_we = 1'h1; prescaler_we = 1'h1;
end end
end end
@ -126,12 +127,12 @@ module timer_core(
timer_new = 32'h0; timer_new = 32'h0;
timer_we = 1'h0; timer_we = 1'h0;
if (timer_set) begin if (timer_rst) begin
timer_new = timer_init; timer_new = 32'h0;
timer_we = 1'h1; timer_we = 1'h1;
end end
else if (timer_dec) begin else if (timer_inc) begin
timer_new = timer_reg - 1'h1; timer_new = timer_reg + 1'h1;
timer_we = 1'h1; timer_we = 1'h1;
end end
end end
@ -144,10 +145,10 @@ module timer_core(
begin : core_ctrl begin : core_ctrl
running_new = 1'h0; running_new = 1'h0;
running_we = 1'h0; running_we = 1'h0;
prescaler_set = 1'h0; prescaler_rst = 1'h0;
prescaler_dec = 1'h0; prescaler_inc = 1'h0;
timer_set = 1'h0; timer_rst = 1'h0;
timer_dec = 1'h0; timer_inc = 1'h0;
core_ctrl_new = CTRL_IDLE; core_ctrl_new = CTRL_IDLE;
core_ctrl_we = 1'h0; core_ctrl_we = 1'h0;
@ -156,20 +157,13 @@ module timer_core(
if (start) begin if (start) begin
running_new = 1'h1; running_new = 1'h1;
running_we = 1'h1; running_we = 1'h1;
prescaler_set = 1'h1; prescaler_rst = 1'h1;
timer_set = 1'h1; timer_rst = 1'h1;
if (prescaler_init == 0) begin
core_ctrl_new = CTRL_TIMER;
core_ctrl_we = 1'h1;
end
else begin
core_ctrl_new = CTRL_PRESCALER; core_ctrl_new = CTRL_PRESCALER;
core_ctrl_we = 1'h1; core_ctrl_we = 1'h1;
end end
end end
end
CTRL_PRESCALER: begin CTRL_PRESCALER: begin
@ -181,13 +175,12 @@ module timer_core(
end end
else begin else begin
if (prescaler_reg == 1) begin if (prescaler_reg == prescaler_init) begin
core_ctrl_new = CTRL_TIMER; core_ctrl_new = CTRL_TIMER;
core_ctrl_we = 1'h1; core_ctrl_we = 1'h1;
end end
else begin else begin
prescaler_dec = 1'h1; prescaler_inc = 1'h1;
end end
end end
end end
@ -200,26 +193,21 @@ module timer_core(
core_ctrl_new = CTRL_IDLE; core_ctrl_new = CTRL_IDLE;
core_ctrl_we = 1'h1; core_ctrl_we = 1'h1;
end end
else begin else begin
if (timer_reg == 1) begin if ((timer_reg == timer_init) & ~free_running) begin
running_new = 1'h0; running_new = 1'h0;
running_we = 1'h1; running_we = 1'h1;
core_ctrl_new = CTRL_IDLE; core_ctrl_new = CTRL_IDLE;
core_ctrl_we = 1'h1; core_ctrl_we = 1'h1;
end end
else begin else begin
timer_dec = 1'h1; timer_inc = 1'h1;
prescaler_rst = 1'h1;
if (prescaler_init > 0) begin
prescaler_set = 1'h1;
core_ctrl_new = CTRL_PRESCALER; core_ctrl_new = CTRL_PRESCALER;
core_ctrl_we = 1'h1; core_ctrl_we = 1'h1;
end end
end end
end end
end
default: begin default: begin
end end

View File

@ -39,6 +39,7 @@ module tb_timer_core();
reg [31 : 0] tb_timer_init; reg [31 : 0] tb_timer_init;
reg tb_start; reg tb_start;
reg tb_stop; reg tb_stop;
reg tb_free_running;
wire [31 : 0] tb_curr_timer; wire [31 : 0] tb_curr_timer;
wire tb_running; wire tb_running;
@ -53,6 +54,7 @@ module tb_timer_core();
.timer_init(tb_timer_init), .timer_init(tb_timer_init),
.start(tb_start), .start(tb_start),
.stop(tb_stop), .stop(tb_stop),
.free_running(tb_free_running),
.curr_timer(tb_curr_timer), .curr_timer(tb_curr_timer),
.running(tb_running) .running(tb_running)
); );
@ -107,13 +109,13 @@ module tb_timer_core();
$display("Internal state:"); $display("Internal state:");
$display("prescaler_reg: 0x%08x, prescaler_new: 0x%08x", $display("prescaler_reg: 0x%08x, prescaler_new: 0x%08x",
dut.prescaler_reg, dut.prescaler_new); dut.prescaler_reg, dut.prescaler_new);
$display("prescaler_set: 0x%1x, prescaler_dec: 0x%1x", $display("prescaler_rst: 0x%1x, prescaler_inc: 0x%1x",
dut.prescaler_set, dut.prescaler_dec); dut.prescaler_rst, dut.prescaler_inc);
$display(""); $display("");
$display("timer_reg: 0x%08x, timer_new: 0x%08x", $display("timer_reg: 0x%08x, timer_new: 0x%08x",
dut.timer_reg, dut.timer_new); dut.timer_reg, dut.timer_new);
$display("timer_set: 0x%1x, timer_dec: 0x%1x", $display("timer_rst: 0x%1x, timer_inc: 0x%1x",
dut.timer_set, dut.timer_dec); dut.timer_rst, dut.timer_inc);
$display(""); $display("");
$display("core_ctrl_reg: 0x%02x, core_ctrl_new: 0x%02x, core_ctrl_we: 0x%1x", $display("core_ctrl_reg: 0x%02x, core_ctrl_new: 0x%02x, core_ctrl_we: 0x%1x",
dut.core_ctrl_reg, dut.core_ctrl_new, dut.core_ctrl_we); dut.core_ctrl_reg, dut.core_ctrl_new, dut.core_ctrl_we);
@ -184,6 +186,7 @@ module tb_timer_core();
tb_start = 1'h0; tb_start = 1'h0;
tb_stop = 1'h0; tb_stop = 1'h0;
tb_free_running = 1'h0;
tb_prescaler_init = 32'h0; tb_prescaler_init = 32'h0;
tb_timer_init = 32'h0; tb_timer_init = 32'h0;
end end