This paper describes an approach for hardware development that involves both imperative and declarative descriptions. The imperative descriptions are mainly used for algorithm and application development; they are based on Cobble, a sequential imperative language extended with facilities for parallel computation and arbitrary-sized variables, similar to the Handel-C language. Operators in Cobble can be produced using the declarative language Pebble, which supports efficient bit-level design. We introduce the use of meta-information, such as information about latency and throughput, for Pebble descriptions, to enable Cobble programs to adapt to different implementations of operators in Pebble. The optimisation of designs by transforming the Cobble and Pebble descriptions is presented.