From: Sebastien Bourdeauducq Date: Mon, 13 May 2013 15:18:30 +0000 (+0200) Subject: timer: atomic reads X-Git-Tag: 24jan2021_ls180~2926 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=581cf5bcb8985ca05de5dd38e53bbd0006a2114f;p=litex.git timer: atomic reads --- diff --git a/milkymist/timer/__init__.py b/milkymist/timer/__init__.py index 32bfb55a..81c36f1c 100644 --- a/milkymist/timer/__init__.py +++ b/milkymist/timer/__init__.py @@ -5,9 +5,11 @@ from migen.bank.eventmanager import * class Timer(Module, AutoCSR): def __init__(self, width=32): - self._en = CSRStorage() - self._value = CSRStorage(width, write_from_dev=True) + self._load = CSRStorage(width) self._reload = CSRStorage(width) + self._en = CSRStorage() + self._update_value = CSR() + self._value = CSRStatus(width) self.submodules.ev = EventManager() self.ev.zero = EventSourceProcess() @@ -15,12 +17,18 @@ class Timer(Module, AutoCSR): ### - self.comb += [ - If(self._value.storage == 0, - self._value.dat_w.eq(self._reload.storage) + value = Signal(width) + self.sync += [ + If(self._en.storage, + If(value == 0, + # set reload to 0 to disable reloading + value.eq(self._reload.storage) + ).Else( + value.eq(value - 1) + ) ).Else( - self._value.dat_w.eq(self._value.storage - 1) + value.eq(self._load.storage) ), - self._value.we.eq(self._en.storage), - self.ev.zero.trigger.eq(self._value.storage != 0) + If(self._update_value.re, self._value.status.eq(value)) ] + self.comb += self.ev.zero.trigger.eq(value != 0) diff --git a/software/bios/boot.c b/software/bios/boot.c index 93d2f279..3cffcef8 100644 --- a/software/bios/boot.c +++ b/software/bios/boot.c @@ -7,9 +7,9 @@ #include #include #include -#include #include +#include #include #include @@ -33,12 +33,13 @@ static int check_ack(void) int recognized; static const char str[SFL_MAGIC_LEN] = SFL_MAGIC_ACK; - timer_enable(0); - timer_set_reload(0); - timer_set_counter(get_system_frequency()/4); - timer_enable(1); + timer0_en_write(0); + timer0_reload_write(0); + timer0_load_write(identifier_frequency_read()/4); + timer0_en_write(1); + timer0_update_value_write(1); recognized = 0; - while(timer_get()) { + while(timer0_value_read()) { if(uart_read_nonblock()) { char c; c = uart_read(); @@ -53,6 +54,7 @@ static int check_ack(void) recognized = 0; } } + timer0_update_value_write(1); } return 0; } diff --git a/software/bios/main.c b/software/bios/main.c index 146882b3..ffdb9e3c 100644 --- a/software/bios/main.c +++ b/software/bios/main.c @@ -8,8 +8,8 @@ #include #include #include -#include +#include #include #include @@ -459,11 +459,12 @@ static int test_user_abort(void) printf("Q/ESC: abort boot\n"); printf("F7: boot from serial\n"); printf("F8: boot from network\n"); - timer_enable(0); - timer_set_reload(0); - timer_set_counter(get_system_frequency()*2); - timer_enable(1); - while(timer_get()) { + timer0_en_write(0); + timer0_reload_write(0); + timer0_load_write(identifier_frequency_read()*2); + timer0_en_write(1); + timer0_update_value_write(1); + while(timer0_value_read()) { if(readchar_nonblock()) { c = readchar(); if((c == 'Q')||(c == '\e')) { @@ -479,6 +480,7 @@ static int test_user_abort(void) return 0; } } + timer0_update_value_write(1); } return 1; } diff --git a/software/include/base/timer.h b/software/include/base/timer.h deleted file mode 100644 index e33e26f5..00000000 --- a/software/include/base/timer.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __TIMER_H -#define __TIMER_H - -#ifdef __cplusplus -extern "C" { -#endif - -unsigned int get_system_frequency(void); -void timer_enable(int en); -unsigned int timer_get(void); -void timer_set_counter(unsigned int value); -void timer_set_reload(unsigned int value); -void busy_wait(unsigned int ms); - -#ifdef __cplusplus -} -#endif - -#endif /* __TIMER_H */ diff --git a/software/libbase/Makefile b/software/libbase/Makefile index 6988f7ae..1a80ed19 100644 --- a/software/libbase/Makefile +++ b/software/libbase/Makefile @@ -1,7 +1,7 @@ M2DIR=../.. include $(M2DIR)/software/common.mak -OBJECTS=setjmp.o libc.o errno.o crc16.o crc32.o console.o timer.o system.o board.o uart.o vsnprintf.o strtod.o qsort.o +OBJECTS=setjmp.o libc.o errno.o crc16.o crc32.o console.o system.o board.o uart.o vsnprintf.o strtod.o qsort.o all: libbase.a diff --git a/software/libbase/board.c b/software/libbase/board.c index c0d9e24d..48764a53 100644 --- a/software/libbase/board.c +++ b/software/libbase/board.c @@ -3,7 +3,6 @@ #include #include #include -#include #include static const struct board_desc boards[1] = { @@ -88,7 +87,7 @@ void board_init(void) } rev = get_pcb_revision(); get_soc_version_formatted(soc_version); - printf("Detected SoC %s at %dMHz on %s (PCB revision %d)\n", soc_version, get_system_frequency()/1000000, + printf("Detected SoC %s at %dMHz on %s (PCB revision %d)\n", soc_version, identifier_frequency_read()/1000000, brd_desc->name, rev); if(strcmp(soc_version, VERSION) != 0) printf("SoC and BIOS versions do not match!\n"); diff --git a/software/libbase/timer.c b/software/libbase/timer.c deleted file mode 100644 index d143b65c..00000000 --- a/software/libbase/timer.c +++ /dev/null @@ -1,37 +0,0 @@ -#include - -#include "timer.h" - -unsigned int get_system_frequency(void) -{ - return identifier_frequency_read(); -} - -void timer_enable(int en) -{ - timer0_en_write(en); -} - -unsigned int timer_get(void) -{ - return timer0_value_read(); -} - -void timer_set_counter(unsigned int value) -{ - timer0_value_write(value); -} - -void timer_set_reload(unsigned int value) -{ - timer0_reload_write(value); -} - -void busy_wait(unsigned int ds) -{ - timer_enable(0); - timer_set_reload(0); - timer_set_counter(get_system_frequency()/10*ds); - timer_enable(1); - while(timer_get()); -} diff --git a/software/libnet/microudp.c b/software/libnet/microudp.c index 55257d83..8c6d6254 100644 --- a/software/libnet/microudp.c +++ b/software/libnet/microudp.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -388,6 +387,16 @@ void microudp_service(void) } } +static void busy_wait(unsigned int ds) +{ + timer0_en_write(0); + timer0_reload_write(0); + timer0_load_write(identifier_frequency_read()/10*ds); + timer0_en_write(1); + timer0_update_value_write(1); + while(timer0_value_read()) timer0_update_value_write(1); +} + void ethreset(void) { minimac_phy_reset_write(0); diff --git a/software/videomixer/time.c b/software/videomixer/time.c index 4f53219c..1f2c3aa9 100644 --- a/software/videomixer/time.c +++ b/software/videomixer/time.c @@ -4,7 +4,12 @@ void time_init(void) { - timer0_reload_write(2*identifier_frequency_read()); + int t; + + timer0_en_write(0); + t = 2*identifier_frequency_read(); + timer0_reload_write(t); + timer0_load_write(t); timer0_en_write(1); } @@ -12,7 +17,8 @@ int elapsed(int *last_event, int period) { int t, dt; - t = timer0_reload_read() - timer0_value_read(); // TODO: atomic read + timer0_update_value_write(1); + t = timer0_reload_read() - timer0_value_read(); dt = t - *last_event; if(dt < 0) dt += timer0_reload_read();