Add separate start, stop bits and running status bit in API

Signed-off-by: Joachim Strömbergson <joachim@assured.se>
This commit is contained in:
Joachim Strömbergson 2023-01-23 13:47:04 +01:00 committed by Daniel Lublin
parent ab03ebd12c
commit 6137b88fe0
5 changed files with 107 additions and 85 deletions

View File

@ -496,9 +496,10 @@ Assigned core prefixes:
|-------------------|-------|-----------|--------|----------|-----------|-------------------------------------------------------------------------| |-------------------|-------|-----------|--------|----------|-----------|-------------------------------------------------------------------------|
| `TRNG_STATUS` | r | r | | | | TRNG_STATUS_READY_BIT is 1 when an entropy word is available. | | `TRNG_STATUS` | r | r | | | | TRNG_STATUS_READY_BIT is 1 when an entropy word is available. |
| `TRNG_ENTROPY` | r | r | 4B | u32 | | Entropy word. Reading a word will clear status. | | `TRNG_ENTROPY` | r | r | 4B | u32 | | Entropy word. Reading a word will clear status. |
| `TIMER_CTRL` | r/w | r/w | | | | If TIMER_STATUS_READY_BIT in TIMER_STATUS is 1, writing anything here | | `TIMER_CTRL` | r/w | r/w | | | | If TIMER_STATUS_RUNNING_BIT in TIMER_STATUS is 0, setting bit 0 starts |
| | | | | | | starts the timer. If the same bit is 0 then writing stops the timer. | | | | | | | | starts the timer. If the TIMER_STATUS_RUNNING_BIT is 1, setting bit 1 |
| `TIMER_STATUS` | r | r | | | | TIMER_STATUS_READY_BIT is 1 when timer is ready to start running. | | | | | | | | stops the timer. |
| `TIMER_STATUS` | r | r | | | | TIMER_STATUS_RUNNING_BIT is 1 when the timer is running. |
| `TIMER_PRESCALER` | r/w | r/w | 4B | | | Prescaler init value. Write blocked when running. | | `TIMER_PRESCALER` | r/w | r/w | 4B | | | Prescaler init value. Write blocked when running. |
| `TIMER_TIMER` | r/w | r/w | 4B | | | Timer init or current value while running. Write blocked when running. | | `TIMER_TIMER` | r/w | r/w | 4B | | | Timer init or current value while running. Write blocked when running. |
| `UDS_FIRST` | r[^3] | invisible | 4B | u8[32] | | First word of Unique Device Secret key. | | `UDS_FIRST` | r[^3] | invisible | 4B | u8[32] | | First word of Unique Device Secret key. |

View File

@ -30,13 +30,15 @@ module timer(
//---------------------------------------------------------------- //----------------------------------------------------------------
// Internal constant and parameter definitions. // Internal constant and parameter definitions.
//---------------------------------------------------------------- //----------------------------------------------------------------
localparam ADDR_CTRL = 8'h08; localparam ADDR_CTRL = 8'h08;
localparam CTRL_START_BIT = 0;
localparam CTRL_STOP_BIT = 1;
localparam ADDR_STATUS = 8'h09; localparam ADDR_STATUS = 8'h09;
localparam STATUS_READY_BIT = 0; localparam STATUS_RUNNING_BIT = 0;
localparam ADDR_PRESCALER = 8'h0a; localparam ADDR_PRESCALER = 8'h0a;
localparam ADDR_TIMER = 8'h0b; localparam ADDR_TIMER = 8'h0b;
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -48,8 +50,11 @@ module timer(
reg [31 : 0] timer_reg; reg [31 : 0] timer_reg;
reg timer_we; reg timer_we;
reg start_stop_reg; reg start_reg;
reg start_stop_new; reg start_new;
reg stop_reg;
reg stop_new;
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -58,7 +63,7 @@ module timer(
reg [31 : 0] tmp_read_data; reg [31 : 0] tmp_read_data;
reg tmp_ready; reg tmp_ready;
wire core_ready; wire core_running;
wire [31 : 0] core_curr_timer; wire [31 : 0] core_curr_timer;
@ -66,7 +71,7 @@ module timer(
// Concurrent connectivity for ports etc. // Concurrent connectivity for ports etc.
//---------------------------------------------------------------- //----------------------------------------------------------------
assign read_data = tmp_read_data; assign read_data = tmp_read_data;
assign ready = tmp_ready; assign ready = tmp_ready;
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -78,10 +83,11 @@ module timer(
.prescaler_init(prescaler_reg), .prescaler_init(prescaler_reg),
.timer_init(timer_reg), .timer_init(timer_reg),
.start_stop(start_stop_reg), .start(start_reg),
.stop(stop_reg),
.curr_timer(core_curr_timer), .curr_timer(core_curr_timer),
.ready(core_ready) .running(core_running)
); );
@ -91,12 +97,14 @@ module timer(
always @ (posedge clk) always @ (posedge clk)
begin : reg_update begin : reg_update
if (!reset_n) begin if (!reset_n) begin
start_stop_reg <= 1'h0; start_reg <= 1'h0;
prescaler_reg <= 32'h0; stop_reg <= 1'h0;
timer_reg <= 32'h0; prescaler_reg <= 32'h0;
timer_reg <= 32'h0;
end end
else begin else begin
start_stop_reg <= start_stop_new; start_reg <= start_new;
stop_reg <= stop_new;
if (prescaler_we) begin if (prescaler_we) begin
prescaler_reg <= write_data; prescaler_reg <= write_data;
@ -116,21 +124,23 @@ module timer(
//---------------------------------------------------------------- //----------------------------------------------------------------
always @* always @*
begin : api begin : api
start_stop_new = 1'h0; start_new = 1'h0;
prescaler_we = 1'h0; stop_new = 1'h0;
timer_we = 1'h0; prescaler_we = 1'h0;
tmp_read_data = 32'h0; timer_we = 1'h0;
tmp_ready = 1'h0; tmp_read_data = 32'h0;
tmp_ready = 1'h0;
if (cs) begin if (cs) begin
tmp_ready = 1'h1; tmp_ready = 1'h1;
if (we) begin if (we) begin
if (address == ADDR_CTRL) begin if (address == ADDR_CTRL) begin
start_stop_new = 1'h1; start_new = write_data[CTRL_START_BIT];
stop_new = write_data[CTRL_STOP_BIT];
end end
if (core_ready) begin if (!core_running) begin
if (address == ADDR_PRESCALER) begin if (address == ADDR_PRESCALER) begin
prescaler_we = 1'h1; prescaler_we = 1'h1;
end end
@ -143,7 +153,7 @@ module timer(
else begin else begin
if (address == ADDR_STATUS) begin if (address == ADDR_STATUS) begin
tmp_read_data = {31'h0, core_ready}; tmp_read_data[STATUS_RUNNING_BIT] = core_running;
end end
if (address == ADDR_PRESCALER) begin if (address == ADDR_PRESCALER) begin
@ -151,9 +161,10 @@ module timer(
end end
if (address == ADDR_TIMER) begin if (address == ADDR_TIMER) begin
if (core_ready) begin if (!core_running) begin
tmp_read_data = timer_reg; tmp_read_data = timer_reg;
end else begin end
else begin
tmp_read_data = core_curr_timer; tmp_read_data = core_curr_timer;
end end
end end

View File

@ -19,10 +19,11 @@ module timer_core(
input wire [31 : 0] prescaler_init, input wire [31 : 0] prescaler_init,
input wire [31 : 0] timer_init, input wire [31 : 0] timer_init,
input wire start_stop, input wire start,
input wire stop,
output wire [31 : 0] curr_timer, output wire [31 : 0] curr_timer,
output wire ready output wire running
); );
@ -37,9 +38,9 @@ module timer_core(
//---------------------------------------------------------------- //----------------------------------------------------------------
// Registers including update variables and write enable. // Registers including update variables and write enable.
//---------------------------------------------------------------- //----------------------------------------------------------------
reg ready_reg; reg running_reg;
reg ready_new; reg running_new;
reg ready_we; reg running_we;
reg [31 : 0] prescaler_reg; reg [31 : 0] prescaler_reg;
reg [31 : 0] prescaler_new; reg [31 : 0] prescaler_new;
@ -62,7 +63,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 ready = ready_reg; assign running = running_reg;
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -72,15 +73,15 @@ module timer_core(
begin: reg_update begin: reg_update
if (!reset_n) if (!reset_n)
begin begin
ready_reg <= 1'h1; running_reg <= 1'h0;
prescaler_reg <= 32'h0; prescaler_reg <= 32'h0;
timer_reg <= 32'h0; timer_reg <= 32'h0;
core_ctrl_reg <= CTRL_IDLE; core_ctrl_reg <= CTRL_IDLE;
end end
else else
begin begin
if (ready_we) begin if (running_we) begin
ready_reg <= ready_new; running_reg <= running_new;
end end
if (prescaler_we) begin if (prescaler_we) begin
@ -141,8 +142,8 @@ module timer_core(
//---------------------------------------------------------------- //----------------------------------------------------------------
always @* always @*
begin : core_ctrl begin : core_ctrl
ready_new = 1'h0; running_new = 1'h0;
ready_we = 1'h0; running_we = 1'h0;
prescaler_set = 1'h0; prescaler_set = 1'h0;
prescaler_dec = 1'h0; prescaler_dec = 1'h0;
timer_set = 1'h0; timer_set = 1'h0;
@ -152,27 +153,29 @@ module timer_core(
case (core_ctrl_reg) case (core_ctrl_reg)
CTRL_IDLE: begin CTRL_IDLE: begin
if (start_stop) if (start) begin
begin running_new = 1'h1;
ready_new = 1'h0; running_we = 1'h1;
ready_we = 1'h1; prescaler_set = 1'h1;
prescaler_set = 1'h1; timer_set = 1'h1;
timer_set = 1'h1;
if (prescaler_init == 0) begin if (prescaler_init == 0) begin
core_ctrl_new = CTRL_TIMER; core_ctrl_new = CTRL_TIMER;
core_ctrl_we = 1'h1; core_ctrl_we = 1'h1;
end else begin end
core_ctrl_new = CTRL_PRESCALER;
core_ctrl_we = 1'h1; else begin
end core_ctrl_new = CTRL_PRESCALER;
end core_ctrl_we = 1'h1;
end
end
end end
CTRL_PRESCALER: begin CTRL_PRESCALER: begin
if (start_stop) begin if (stop) begin
ready_new = 1'h1; running_new = 1'h0;
ready_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
@ -181,7 +184,9 @@ module timer_core(
if (prescaler_reg == 1) begin if (prescaler_reg == 1) begin
core_ctrl_new = CTRL_TIMER; core_ctrl_new = CTRL_TIMER;
core_ctrl_we = 1'h1; core_ctrl_we = 1'h1;
end else begin end
else begin
prescaler_dec = 1'h1; prescaler_dec = 1'h1;
end end
end end
@ -189,17 +194,17 @@ module timer_core(
CTRL_TIMER: begin CTRL_TIMER: begin
if (start_stop) begin if (stop) begin
ready_new = 1'h1; running_new = 1'h0;
ready_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
if (timer_reg == 1) begin if (timer_reg == 1) begin
ready_new = 1'h1; running_new = 1'h0;
ready_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

View File

@ -37,9 +37,10 @@ module tb_timer_core();
reg tb_reset_n; reg tb_reset_n;
reg [31 : 0] tb_prescaler_init; reg [31 : 0] tb_prescaler_init;
reg [31 : 0] tb_timer_init; reg [31 : 0] tb_timer_init;
reg tb_start_stop; reg tb_start;
reg tb_stop;
wire [31 : 0] tb_curr_timer; wire [31 : 0] tb_curr_timer;
wire tb_ready; wire tb_running;
//---------------------------------------------------------------- //----------------------------------------------------------------
@ -50,9 +51,10 @@ module tb_timer_core();
.reset_n(tb_reset_n), .reset_n(tb_reset_n),
.prescaler_init(tb_prescaler_init), .prescaler_init(tb_prescaler_init),
.timer_init(tb_timer_init), .timer_init(tb_timer_init),
.start_stop(tb_start_stop), .start(tb_start),
.stop(tb_stop),
.curr_timer(tb_curr_timer), .curr_timer(tb_curr_timer),
.ready(tb_ready) .running(tb_running)
); );
@ -99,8 +101,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_stop: 0x%1x, ready: 0x%1x", $display("start: 0x%1x, stop: 0x%1x, running: 0x%1x",
dut.start_stop, dut.ready); dut.start, dut.stop, dut.running);
$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",
@ -141,18 +143,18 @@ module tb_timer_core();
//---------------------------------------------------------------- //----------------------------------------------------------------
// wait_ready() // wait_done()
// //
// Wait for the ready flag in the dut to be set. // Wait for the running flag in the dut to be dropped.
// //
// Note: It is the callers responsibility to call the function // Note: It is the callers responsibility to call the function
// when the dut is actively processing and will in fact at some // when the dut is actively processing and will in fact at some
// point set the flag. // point set the flag.
//---------------------------------------------------------------- //----------------------------------------------------------------
task wait_ready; task wait_done;
begin begin
#(2 * CLK_PERIOD); #(2 * CLK_PERIOD);
while (!tb_ready) while (tb_running)
begin begin
#(CLK_PERIOD); #(CLK_PERIOD);
if (DUMP_WAIT) if (DUMP_WAIT)
@ -172,17 +174,18 @@ module tb_timer_core();
//---------------------------------------------------------------- //----------------------------------------------------------------
task init_sim; task init_sim;
begin begin
cycle_ctr = 0; cycle_ctr = 0;
error_ctr = 0; error_ctr = 0;
tc_ctr = 0; tc_ctr = 0;
tb_monitor = 0; tb_monitor = 0;
tb_clk = 0; tb_clk = 0;
tb_reset_n = 1; tb_reset_n = 1;
tb_start_stop = 1'h0; tb_start = 1'h0;
tb_prescaler_init = 32'h0; tb_stop = 1'h0;
tb_timer_init = 32'h0; tb_prescaler_init = 32'h0;
tb_timer_init = 32'h0;
end end
endtask // init_sim endtask // init_sim
@ -200,10 +203,10 @@ module tb_timer_core();
tb_prescaler_init = 32'h6; tb_prescaler_init = 32'h6;
tb_timer_init = 32'h9; tb_timer_init = 32'h9;
#(CLK_PERIOD); #(CLK_PERIOD);
tb_start_stop = 1'h1; tb_start = 1'h1;
#(CLK_PERIOD); #(CLK_PERIOD);
tb_start_stop = 1'h0; tb_start = 1'h0;
wait_ready(); wait_done();
#(CLK_PERIOD); #(CLK_PERIOD);
tb_monitor = 0; tb_monitor = 0;
$display("--- test1 completed."); $display("--- test1 completed.");

View File

@ -48,8 +48,10 @@ enum {
TK1_MMIO_TRNG_ENTROPY = TK1_MMIO_TRNG_BASE | 0x80, TK1_MMIO_TRNG_ENTROPY = TK1_MMIO_TRNG_BASE | 0x80,
TK1_MMIO_TIMER_CTRL = TK1_MMIO_TIMER_BASE | 0x20, TK1_MMIO_TIMER_CTRL = TK1_MMIO_TIMER_BASE | 0x20,
TK1_MMIO_TIMER_CTRL_START_BIT = 0,
TK1_MMIO_TIMER_CTRL_STOP_BIT = 1,
TK1_MMIO_TIMER_STATUS = TK1_MMIO_TIMER_BASE | 0x24, TK1_MMIO_TIMER_STATUS = TK1_MMIO_TIMER_BASE | 0x24,
TK1_MMIO_TIMER_STATUS_READY_BIT = 0, TK1_MMIO_TIMER_STATUS_RUNNING_BIT = 0,
TK1_MMIO_TIMER_PRESCALER = TK1_MMIO_TIMER_BASE | 0x28, TK1_MMIO_TIMER_PRESCALER = TK1_MMIO_TIMER_BASE | 0x28,
TK1_MMIO_TIMER_TIMER = TK1_MMIO_TIMER_BASE | 0x2c, TK1_MMIO_TIMER_TIMER = TK1_MMIO_TIMER_BASE | 0x2c,