Superscalar processors and complex instructions
You should understand that any program is a sequence of instructions (ok, you an think of it as a collection of threads, where every thread is a sequence of instructions or a virtual process that executes that series of instructions). The instructions are supposed to be executed one after another. Single pipeline processor fetches instruction as they are ought to, every clock cycle and keeps its functional unit executing an instruction per cycle. This is not very true actually because execution takes multiple cycles and you fetch next instruction before previous is complete. But we pretend that instructions are still executed one after another and you still need one FU. Superscalars, however, cheat. They tell to the user that they still execute her program as designed, one instruction after another, yet take a window of neighbor instructions and execute them at once. They introduce extra FUs (Wikipedia called them "redundant") for this technique, called "Instruction Level Parallelism" (ILP).

Superscalars also have to entail a complex dependency detection and maintenance mechanism. As Amdahl has explained), because instructions of the same thread operate on the same data set, you have a lot of dependencies, especially among neighbor instructions and, thus cannot gain a lot of parallelism at ILP. The parallel pipelines are therefore sometimes used to execute different threads. This is full-scale parallelism already (except the synchronization cases and cache contention, which prevents any advantage of TLP over ILP, especially if von Neumann bottleneck is considered). Such TLP is known as hyperthreading. Yet, it is true parallelism since now threads are indeed executed in parallel, as if there are multiple cores, rather than parallelism is emulated by periodically switching threads on a single pipeline and, therefore, is also called "simultaneous multithreading". 

I do not even see any reason to differentiate between multicore and hyperthreading. Since different pipelines execute different threads, this means that they have separate instruction pointer, set of registers and everything you need for the context, which are switched. Might be the common cache and shared FUs is the only things that distinguishes single core from multiple cores. Yes, shared cache. This may save you from cache incoherence /memory consistence problems that can happen in truly multicore system.