which themselves are implementations.
as an example, one common thing between software and hardware is the idea of coupling. In HDL, this expresses itself very often in a block diagram.
eg, module A sends signals to B and C. B sends signals to C. C sends signals to D.
In such cases, I will generally have module A send signals only to B, and B to C, C to D. this simplifies the block diagram. It might seem silly for A to communicate with C by sending signals through B, but it often makes things easier. Further, it allows for the formation of generic interfaces to a much larger extent. In software, this is similar to "chain of command", at least to some degree. For hardware it becomes very nice when you need to balance pipeline delays (both in terms of cycles, and qualified clock cycles). It also becomes useful when FIFO's and processing is done between two communicating modules.
Like I've said, the structural patterns lend themselves to HDL designs in fairly obvious ways. visitor and chain of command are fairly common.
But design goals heavily influence what you can and can't do in logic. design for pipelines, c-slow, reconfiguration, multi-clocks, gated-clocks, streaming, non-streaming, blocks at a time, etc... is all different. For example, c-slow and reconfigurable logic place some limitations on the FPGA resources. multi-clock designs clearly have domain crossings that need to be addressed. gated clocks and non-streaming designs become difficult to pipeline because flushing must occur. the idea of processing blocks at a time becomes difficult if blocks can be fragmented, variable size, etc... design for simulation, for test, for etc... are all other goals that must be considered. Each places slightly different restrictions on what you can and can't do.
and as before, the HW/SW boundary should always be considered. There are so many times when a simple 8b uC can be used to implement slow logic, but instead it is implemented using months of work and 10-25% of an FPGA.
unfortunantly, I've not seen any good books on the topic. "Reconfiguarable Computing" details high-level synthesis and transaction level modeling, and a few stream-processing and other paradigms (including c-slow), but overall it not that close to what you want.
@ mrfibble:
making the feedback requirements loose also allows large and often complex portions of control logic become simple. This becomes important even if c-slowing can't be applied. Further, b-processing often allows for this case.