UCSBarchlab / PyRTL

A collection of classes providing simple hardware specification, simulation, tracing, and testing suitable for teaching and research. Simplicity, usability, clarity, and extensibility are the overarching goals, rather than performance or optimization.
http://ucsbarchlab.github.io/PyRTL
BSD 3-Clause "New" or "Revised" License
257 stars 78 forks source link

Allow integer shift amounts for shifter corecircuits #356

Closed mdko closed 3 years ago

mdko commented 3 years ago

Currently, shifting by an integer is not allowed in PyRTL. So instead of being able to do

pyrtl.shift_left_logical(w, 2)

you currently have to do

pyrtl.concat(w[:-2], pyrtl.Const(0, 2))

This PR allows shifting by an integer literal since the workaround is a little verbose/unintuitive.

Rather than causing a barrel shifter to be created in these cases, the PR uses an optimization that essentially checks for the integer literal cases, and in these cases, does a concatenation or slice as needed. Thus, the unoptimized netlist remains relatively clean.

For example, this given this code:

i = pyrtl.Input(8, 'i')
o = pyrtl.Output(8, 'o')
o <<= pyrtl.shift_left_arithmetic(i, 2)  # or logical

using a barrel shifter would produce the following graphical output:

shift_test_sla_barrel_shifter

while using this small optimization produces:

shift_test_sla_new

They are logically the same, and when optimized synthesize down to the same size final netlist:

shift_test_sla_new_synth_opt