Imperative languages only implicitly have a notion of time. Primarily, demarcated by mutation of state, i.e. there's a before some variable was mutated and an after some variable was mutated. Declarative languages, as you say, don't have a notion of time unless they explicitly model it. There are a variety of ways of modeling time. Ptolemy II has a rather comprehensive framework and analysis, so I highly recommend looking at it and reading the book System Design, Modeling, and Simulation using Ptolemy II.
Hardware description languages (HDLs) are typically synchronous reactive (SR) languages like Lucid Synchrone, Esterel, and Sig. (Note, these are not HDLs but languages with a similar programming model.) The Dedalus language can be thought of as a synchronous reactive language, though that wasn't really the intent behind it. It nevertheless gives a concrete model of what's happening. Discrete functional reactive programming is a similar but distinct approach.
Another class of languages that are complementary is synchronous (or static) dataflow (SDF) languages such as StreamIt. The word "synchronous" here is being used in a different sense than in "synchronous reactive". Synchronous dataflow languages are probably better thought of as stream processing languages and they are widely used for signal processing tasks of various sorts. There are connections between these two models. A synchronous reactive program with no feedback corresponds to a homogeneous synchronous dataflow program. In a synchronous dataflow program, we have a bunch of stream processing functions where we know statically how many elements in each input stream each function consumes to produce a given number of elements in their output streams. If the rates are consistent — which can be statically checked — then it is possible to schedule the code so the inputs are always available and buffers with fixed, statically known sizes can be used. This model doesn't actually have a notion of time, but if the overall input streams represent regularly timed events, then the rates gain temporal significance.
The synchronous reactive model does have an explicit notion of time. In this model, there's a global (logical) clock. Every function is called on each tick. We can think of this as like the synchronous dataflow model except every stream processing function has a 1:1 rate. However, unlike the synchronous dataflow model, values can be absent and we can detect this. Another difference from the synchronous dataflow model in some synchronous reactive languages is that calculating a value at a particular time may (conceptually) require a fixed point calculation because the scheduling (within a tick) is data dependent. It's typically possible to do static checks to avoid this situation entirely.
Usually synchronous reactive systems allow different rates for different stream processing functions and this is what the absent values are typically used for. Conceptually, there's a "fastest" logical clock and every stream processing function is executed on every tick of that clock and running on a different (slower) clock means producing absent values for some ticks of the faster clock. To avoid needing to actually represent the absence/presence of values, static analyses can be done to make sure every stream processing function only attempts to read present values. Lucid Synchrone has a fairly sophisticated approach involving a type system and clock variables. It does also support explicitly reifying the absence/presence via its signal feature.
All the discussion above has used a logical notion of time. It's easy to go from there to a notion of real time by simply specifying a rate for the top-level fastest clock(s). However, the logical time model treats calculations as happening instantaneously. The execution time can be modeled by inserting delays into operations and/or using clocks running at different rates. However, while VHDL and Verilog do use a programming model similar to what I've described above, and they do provide annotations to specify timing, the latter are more descriptive than prescriptive. A functional simulation doesn't need them and the synthesizer ignores them (i.e. it assumes they accurately describe the chosen hardware). The annotations get used for timing simulations. In a functional simulation, the delays that need to exist for situations like your flip-flop to have a well-defined behavior are called delta delays and are conceptualized as "infinitesimal" time delays. In the SDF model, these delays would happen automatically. In a synchronous reactive model delays would need to be inserted (though will typically be embedded in primitives) and the delta delays correspond to ticks of the global logical clock. The notion of superdense time described in the Ptolemy II book in section 1.7.2 may also be a useful tool here.
So, in a hardware description language time enters in two distinct but correlated way. One is as an implicit part of the programming model and as a more logical notion. Another as explicit annotations to be used for timing simulation that can interact with the programming model. The latter can be coupled to the former by modeling the timing annotations as finite delays in terms of a sufficiently fine-grained logical clock. This requires delays be specified for everything (directly or indirectly) and is more computationally-intensive to model than the functional simulation (if for no other reason) because it's doing essentially the same thing at a finer grain. Sometimes the functional simulation is described as a Discrete Event (DE) simulation (another model of time described in the Ptolemy II book), but for synchronous sequential logic this more or less reduces to SDF or SR. (In general, in the DE model you can schedule an event to happen at any time in the future and simulation of it involves repeatedly processing the earliest unprocessed event in a priority queue. In [synchronous] sequential logic, events are being produced regularly and for a HDL "scheduling" something for the [distant, i.e. more than a cycle away] future would be explicitly modeled by, say, decrementing a counter until it reached 0.)