ieee754.add package

Submodules

ieee754.add.add_shift_experiment module

ieee754.add.dual_add_experiment module

ieee754.add.example_comb_pipe module

ieee754.add.f module

ieee754.add.fifo module

ieee754.add.fsqr module

ieee754.add.function_unit module

ieee754.add.hmc_backed_fifo_tb module

ieee754.add.inputgroup module

class ieee754.add.inputgroup.FPGetSyncOpsMod(width, num_ops=2)

Bases: object

elaborate(platform)
ports()
class ieee754.add.inputgroup.FPOps(width, num_ops)

Bases: ieee754.fpcommon.fpbase.Trigger

ports()
class ieee754.add.inputgroup.InputGroup(width, num_ops=2, num_rows=4)

Bases: object

elaborate(platform)
ports()

ieee754.add.original_single_pipe module

Pipeline and BufferedHandshake implementation, conforming to the same API.

eq: –

a strategically very important function that is identical in function to nmigen’s Signal.eq function, except it may take objects, or a list of objects, or a tuple of objects, and where objects may also be Records.

Stage API:

stage requires compliance with a strict API that may be implemented in several means, including as a static class. the methods of a stage instance must be as follows:

  • ispec() - Input data format specification
    returns an object or a list or tuple of objects, or a Record, each object having an “eq” function which takes responsibility for copying by assignment all sub-objects
  • ospec() - Output data format specification
    requirements as for ospec
  • process(m, i) - Processes an ispec-formatted object
    returns a combinatorial block of a result that may be assigned to the output, by way of the “eq” function
  • setup(m, i) - Optional function for setting up submodules
    may be used for more complex stages, to link the input (i) to submodules. must take responsibility for adding those submodules to the module (m). the submodules must be combinatorial blocks and must have their inputs and output linked combinatorially.

StageChain:

A useful combinatorial wrapper around stages that chains them together and then presents a Stage-API-conformant interface.

UnbufferedPipeline:

A simple stalling clock-synchronised pipeline that has no buffering (unlike BufferedHandshake). A stall anywhere along the line will result in a stall back-propagating down the entire chain.

The BufferedHandshake by contrast will buffer incoming data, allowing previous stages one clock cycle’s grace before also having to stall.

BufferedHandshake:

nmigen implementation of buffered pipeline stage, based on zipcpu: https://zipcpu.com/blog/2017/08/14/strategies-for-pipelining.html

this module requires quite a bit of thought to understand how it works (and why it is needed in the first place). reading the above is strongly recommended.

unlike john dawson’s IEEE754 FPU STB/ACK signalling, which requires the STB / ACK signals to raise and lower (on separate clocks) before data may proceeed (thus only allowing one piece of data to proceed on ALTERNATE cycles), the signalling here is a true pipeline where data will flow on every clock when the conditions are right.

input acceptance conditions are when:
  • incoming previous-stage strobe (p.valid_i) is HIGH
  • outgoing previous-stage ready (p.ready_o) is LOW
output transmission conditions are when:
  • outgoing next-stage strobe (n.valid_o) is HIGH
  • outgoing next-stage ready (n.ready_i) is LOW

the tricky bit is when the input has valid data and the output is not ready to accept it. if it wasn’t for the clock synchronisation, it would be possible to tell the input “hey don’t send that data, we’re not ready”. unfortunately, it’s not possible to “change the past”: the previous stage has no choice but to pass on its data.

therefore, the incoming data must be accepted - and stored: that is the responsibility / contract that this stage must accept. on the same clock, it’s possible to tell the input that it must not send any more data. this is the “stall” condition.

we now effectively have two possible pieces of data to “choose” from: the buffered data, and the incoming data. the decision as to which to process and output is based on whether we are in “stall” or not. i.e. when the next stage is no longer ready, the output comes from the buffer if a stall had previously occurred, otherwise it comes direct from processing the input.

this allows us to respect a synchronous “travelling STB” with what dan calls a “buffered handshake”.

it’s quite a complex state machine!

class ieee754.add.original_single_pipe.BufferedHandshake(stage)

Bases: ieee754.add.original_single_pipe.PipelineBase

buffered pipeline stage. data and strobe signals travel in sync. if ever the input is ready and the output is not, processed data is stored in a temporary register.

Argument: stage. see Stage API above

stage-1 p.valid_i >>in stage n.valid_o out>> stage+1 stage-1 p.ready_o <<out stage n.ready_i <<in stage+1 stage-1 p.data_i >>in stage n.data_o out>> stage+1

process —>—-^

+– r_data ->-+

input data p.data_i is read (only), is processed and goes into an intermediate result store [process()]. this is updated combinatorially.

in a non-stall condition, the intermediate result will go into the output (update_output). however if ever there is a stall, it goes into r_data instead [update_buffer()].

when the non-stall condition is released, r_data is the first to be transferred to the output [flush_buffer()], and the stall condition cleared.

on the next cycle (as long as stall is not raised again) the input may begin to be processed and transferred directly to output.

elaborate(platform)
class ieee754.add.original_single_pipe.ExampleAddStage

Bases: object

an example of how to use the buffered pipeline, as a class instance

ispec()

returns a tuple of input signals which will be the incoming data

ospec()

returns an output signal which will happen to contain the sum of the two inputs

process(i)

process the input data (sums the values in the tuple) and returns it

class ieee754.add.original_single_pipe.ExampleBufPipe

Bases: ieee754.add.original_single_pipe.BufferedHandshake

an example of how to use the buffered pipeline.

class ieee754.add.original_single_pipe.ExampleBufPipeAdd

Bases: ieee754.add.original_single_pipe.BufferedHandshake

an example of how to use the buffered pipeline, using a class instance

class ieee754.add.original_single_pipe.ExamplePipeline

Bases: ieee754.add.original_single_pipe.UnbufferedPipeline

an example of how to use the combinatorial pipeline.

class ieee754.add.original_single_pipe.ExampleStage

Bases: object

an example of how to use the buffered pipeline, in a static class fashion

ispec()
ospec()
process()

process the input data and returns it (adds 1)

class ieee754.add.original_single_pipe.ExampleStageCls

Bases: object

an example of how to use the buffered pipeline, in a static class fashion

ispec()
ospec()
process(i)

process the input data and returns it (adds 1)

class ieee754.add.original_single_pipe.NextControl

Bases: object

contains the signals that go to the next stage (both in and out) * valid_o: output indicating to next stage that data is valid * ready_i: input from next stage indicating that it can accept data * data_o : an output - added by the user of this class

connect_out(nxt)

helper function to connect stage to an output source. do not use to connect stage-to-stage!

connect_to_next(nxt)

helper function to connect to the next stage data/valid/ready. data/valid is passed TO nxt, and ready comes IN from nxt.

class ieee754.add.original_single_pipe.PipelineBase(stage, in_multi=None)

Bases: object

Common functions for Pipeline API

connect_in(prev)

helper function to connect stage to an input source. do not use to connect stage-to-stage!

connect_out(nxt)

helper function to connect stage to an output source. do not use to connect stage-to-stage!

connect_to_next(nxt)

helper function to connect to the next stage data/valid/ready.

ports()
set_input(i)

helper function to set the input data

class ieee754.add.original_single_pipe.PrevControl(i_width=1)

Bases: object

contains signals that come from the previous stage (both in and out) * valid_i: previous stage indicating all incoming data is valid.

may be a multi-bit signal, where all bits are required to be asserted to indicate “valid”.
  • ready_o: output to next stage indicating readiness to accept data
  • data_i : an input - added by the user of this class
connect_in(prev)

helper function to connect stage to an input source. do not use to connect stage-to-stage!

valid_i_logic()
class ieee754.add.original_single_pipe.StageChain(chain)

Bases: object

pass in a list of stages, and they will automatically be chained together via their input and output specs into a combinatorial chain.

  • input to this class will be the input of the first stage
  • output of first stage goes into input of second
  • output of second goes into input into third (etc. etc.)
  • the output of this class will be the output of the last stage
ispec()
ospec()
process(i)
setup(m, i, assigntemp=False)
class ieee754.add.original_single_pipe.UnbufferedPipeline(stage)

Bases: ieee754.add.original_single_pipe.PipelineBase

A simple pipeline stage with single-clock synchronisation and two-way valid/ready synchronised signalling.

Note that a stall in one stage will result in the entire pipeline chain stalling.

Also that unlike BufferedHandshake, the valid/ready signalling does NOT travel synchronously with the data: the valid/ready signalling combines in a combinatorial fashion. Therefore, a long pipeline chain will lengthen propagation delays.

Argument: stage. see Stage API, above

stage-1 p.valid_i >>in stage n.valid_o out>> stage+1 stage-1 p.ready_o <<out stage n.ready_i <<in stage+1 stage-1 p.data_i >>in stage n.data_o out>> stage+1

r_data result

+–process ->-+

p.data_i : StageInput, shaped according to ispec
The pipeline input
p.data_o : StageOutput, shaped according to ospec
The pipeline output
r_data : input_shape according to ispec
A temporary (buffered) copy of a prior (valid) input. This is HELD if the output is not ready. It is updated SYNCHRONOUSLY.
result: output_shape according to ospec
The output of the combinatorial logic. it is updated COMBINATORIALLY (no clock dependence).
elaborate(platform)
ieee754.add.original_single_pipe.eq(o, i)

makes signals equal: a helper routine which identifies if it is being passed a list (or tuple) of objects, or signals, or Records, and calls the objects’ eq function.

complex objects (classes) can be used: they must follow the convention of having an eq member function, which takes the responsibility of further calling eq and returning a list of eq assignments

Record is a special (unusual, recursive) case, where the input may be specified as a dictionary (which may contain further dictionaries, recursively), where the field names of the dictionary must match the Record’s field spec. Alternatively, an object with the same member names as the Record may be assigned: it does not have to be a Record.

ieee754.add.pipeline_example module

ieee754.add.pipeline_example2 module

ieee754.add.record_experiment module

ieee754.add.rstation_row module

ieee754.add.run_test module

ieee754.add.slice_repro module

ieee754.add.test_add_pipe module

ieee754.add.test_dual module

ieee754.add.test_fpdiv_pipe module

ieee754.add.test_fpnum module

ieee754.add.test_inputgroup module

ieee754.add.test_multishift module

class ieee754.add.test_multishift.MultiShiftModL(width)

Bases: object

elaborate(platform=None)
class ieee754.add.test_multishift.MultiShiftModR(width)

Bases: object

elaborate(platform=None)
class ieee754.add.test_multishift.MultiShiftModRMod(width)

Bases: object

elaborate(platform=None)
class ieee754.add.test_multishift.MultiShiftRMergeMod(width)

Bases: object

elaborate(platform=None)
ieee754.add.test_multishift.check_case(dut, width, a, b)
ieee754.add.test_multishift.check_case_merge(dut, width, a, b)
ieee754.add.test_multishift.check_caser(dut, width, a, b)
ieee754.add.test_multishift.testbench(dut)
ieee754.add.test_multishift.testbenchr(dut)
ieee754.add.test_multishift.testmerge(dut)

ieee754.add.test_orgate module

class ieee754.add.test_orgate.ORGate

Bases: object

elaborate(platform=None)
ieee754.add.test_orgate.check_case(a, b, x)
ieee754.add.test_orgate.testbench()

ieee754.add.test_state_add module

ieee754.add.test_syncops module

Module contents