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

View File

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

View File

@ -255,7 +255,7 @@ module tb_timer();
// test1() // test1()
// //
// Set timer and scaler and then start the timer. Wait // 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; task test1;
begin : test1 begin : test1
@ -275,12 +275,13 @@ module tb_timer();
write_word(ADDR_TIMER, 32'h9); write_word(ADDR_TIMER, 32'h9);
time_expected = 32'h6 * 32'h9; time_expected = 32'h6 * 32'h9;
// Start the timer.
write_word(ADDR_CTRL, 32'h1); write_word(ADDR_CTRL, 32'h1);
time_start = cycle_ctr; time_start = cycle_ctr;
#(CLK_PERIOD); #(CLK_PERIOD);
read_word(ADDR_STATUS); read_word(ADDR_STATUS);
while (read_data) begin while (read_data != 3) begin
read_word(ADDR_STATUS); read_word(ADDR_STATUS);
end end
time_stop = cycle_ctr; time_stop = cycle_ctr;
@ -296,10 +297,13 @@ module tb_timer();
error_ctr = error_ctr + 1; error_ctr = error_ctr + 1;
end end
// Stop the timer.
write_word(ADDR_CTRL, 32'h2);
$display("--- test1: completed."); $display("--- test1: completed.");
$display(""); $display("");
end end
endtask // tes1 endtask // test1
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -373,7 +377,7 @@ module tb_timer();
$display(""); $display("");
$display("--- test3: started."); $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_PRESCALER, 32'h2);
write_word(ADDR_TIMER, 32'h9); write_word(ADDR_TIMER, 32'h9);

View File

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