Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"enum" parameter bitstream mapping #52

Closed
gatecat opened this issue Aug 19, 2022 · 6 comments
Closed

"enum" parameter bitstream mapping #52

gatecat opened this issue Aug 19, 2022 · 6 comments

Comments

@gatecat
Copy link
Collaborator

gatecat commented Aug 19, 2022

consider this somewhat pointless example of a primitive the end user might instantiate

module LOGIC_GATE(input A, B, output X);
parameter MODE = "AND";
generate
   if (MODE == "AND") assign X = A & B;
   else if (MODE == "OR") assign X = A | B;
   else if (MODE == "XOR") assign X = A ^ B;
endgenerate
endmodule

this would generate a FASM configuration feature in nextpnr like X6Y9A.MODE.AND or X6Y9A.MODE.XOR

the underlying hardware primitive might look like

module LOGIC_GATE(input A, B, input [1:0] ConfigBits, output X);
parameter MODE = "AND";

assign X = (ConfigBits == 2'b01) ? (A & B) :
   (ConfigBits == 2'b10) ? (A | B) :
  (ConfigBits == 2'b11) ? (A ^ B) :
  1'bx;

endmodule

we now need some way of specifying the mapping of

MODE.AND => ConfigBits[1:0]=2'b01
MODE.OR => ConfigBits[1:0]=2'b10
MODE.XOR => ConfigBits[1:0]=2'b11

the encoding being just an example, others might be possible

one way of doing this using attributes might be like

(* FABulous, BelMap,
MODE_start=0,
MODE_end=1,
MODE_enum,
MODE_AND=2'b01,
MODE_OR=2'b10,
MODE_XOR=2'b11,
*)

essentially, we need to specify more things for MODE than just a single bit mapping - the range of bits it maps to and the set of possible values. Same for multi-bit non-enumarated configuration values (like the initial accumulator value of a DSP), which in this syntax could perhaps just specify _start and _end attributes without any of the enum stuff.

@KelvinChung2000
Copy link
Collaborator

I am thinking maybe something like this:

(* FABulous, BelEnum, MODE.
ADD,
OR,
XOR
*)
(* Fabulous, BelMap,
start=0,
end=1,
some_init_value=Vector(2)
MODE
*)

Then the AND, OR, XOR will get automatically assigned to b00, b01, b10. This might make parsing multiple enums easier. The Vector(2) will be indicated using 2 bits for the some_init_value

@gatecat
Copy link
Collaborator Author

gatecat commented Aug 19, 2022

Then the AND, OR, XOR will get automatically assigned to b00, b01, b10

We want to have the ability to support custom encodings though.

Actually, Dirk did suggest out-of-band going back to hot comments here, if that's easier to work with. Something like

// bitstream encoding
// parameter MODE [1:0]
// AND=2'b01
// ..
// end MODE

this would specify that MODE is located in bits 1..0 and the encoding of AND etc
but we could maybe have something like this as attributes still too?

@KelvinChung2000
Copy link
Collaborator

I don't think going back to comment will be a good idea.
This should just do the same,

(* FABulous, BelEnum, MODE[1:0],
ADD=01,
OR=10,
XOR=11
*)

@gatecat
Copy link
Collaborator Author

gatecat commented Aug 19, 2022

Looks good!

@KelvinChung2000
Copy link
Collaborator

Now the following Bel map:

(* FABulous, BelEnum, MODE1[1:0],
A=001,
B=010,
C=011,
*)
(* FABulous, BelEnum, MODE2[0:1],
ADD=01,
OR=10,
XOR=11
*)
(* Fabulous, BelMap,
test=0,
MODE2,
some_init_value1=1:0,
some_init_value2=0:1,
MODE1
*)

will yield the following dictionary after parsing.

{
   "test":{
      "0":{
         "0":"1"
      }
   },
   "MODE2":{
      "ADD":{
         "0":"0",
         "1":"1"
      },
      "OR":{
         "0":"1",
         "1":"0"
      },
      "XOR":{
         "0":"1",
         "1":"1"
      }
   },
   "some_init_value1":{
      "3":{
         "1":"1",
         "0":"1"
      },
      "2":{
         "1":"1",
         "0":"0"
      },
      "1":{
         "1":"0",
         "0":"1"
      },
      "0":{
         "1":"0",
         "0":"0"
      }
   },
   "some_init_value2":{
      "0":{
         "1":"1",
         "0":"1"
      },
      "1":{
         "1":"1",
         "0":"0"
      },
      "2":{
         "1":"0",
         "0":"1"
      },
      "3":{
         "1":"0",
         "0":"0"
      }
   },
   "MODE1":{
      "A":{
         "1":"0",
         "0":"0"
      },
      "B":{
         "1":"0",
         "0":"1"
      },
      "C":{
         "1":"0",
         "0":"1"
      }
   }
}

I have further looked into bitstream generation to support with an enum, but it looks like that will also require refactoring.

@gatecat
Copy link
Collaborator Author

gatecat commented Aug 22, 2022

looks good!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants