B-Lang-org / bsc

Bluespec Compiler (BSC)
Other
902 stars 141 forks source link

module verilog does not allow sharing ports among conflicting methods #658

Open mieszko opened 6 months ago

mieszko commented 6 months ago

suppose we have an interface to a Verilog primitive with two action methods:

interface Foobar =
    foo :: Bit 1 -> PrimAction
    bar :: Bit 1 -> PrimAction

and that those methods can never both be called at the same time, so they share the port for their argument (not a rare thing in RTL):

mkFoobar :: Module Foobar
mkFoobar = liftModule $
    module verilog "foobar" "clk"
        foo = "QUX" "EN_FOO"
        bar = "QUX" "EN_BAR"
      [ foo >< foo, bar >< bar, foo >< bar ]

now synthesizing this:

{-# synthesize mkTest #-}
mkTest :: Module Empty
mkTest = module
    baz <- mkFoobar
    return _

results in an ICE:

acheck:chkDupWires
fromList [baz$QUX[IdPMeth,IdP_enable,IdPProbe]]
Internal Bluespec Compiler Error:
Please report this failure to the BSC developers [...]

this seems to be because baz$QUX appears on the wire list twice, so i guess it's really failing on the signal in mkTest.

it would be nice if bsc permitted the shared port without an additional layer of RTL wrapping and generated the mux. in general i guess this makes sense for arguments (only if the methods are ><) and results.

another related example that fails for the same reason, this time with the enable:

interface Foobar =
    foo :: PrimAction
    bar :: PrimAction

mkFoobar :: Module Foobar
mkFoobar = liftModule $
    module verilog "foobar" "clk"
        foo = "?"
        bar = "?"
      [ foo >< foo, bar >< bar, foo <> bar ]

in this case it should probably fail with a nice error message that says "?" is only valid with {inhigh}, since the way bsc generates RTL interfaces it expects enables to be single wires (although i can imagine they could correspond to combinations of signals, e.g., a RAM might have ce and we, with ce && !we = read and ce && we = write).

(i suppose bsc should also check that the identifier is a valid Verilog identifier — or autoescape it, see discussion under #654 — since it will happily generate nonsense RTL if one names a method argument "?")

anyway at least these examples shouldn't produce an ICE.