-
-
Notifications
You must be signed in to change notification settings - Fork 303
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
new condtion syntactic suga #1410
Comments
Hi @jijingg, I think there is something quite close already via the spinal.lib.WhenBuilder : import spinal.lib._
val conds = Bits(8 bits)
val result = UInt(8 bits)
val ctx = WhenBuilder()
ctx.when(conds(0)) {
result := 0
}
ctx.when(conds(1)) {
result := 1
}
if(true){
ctx.when(conds(2)) {
result := 2
}
}
ctx.when(conds(3)) {
result := 3
}
for(i <- 5 to 7) ctx.when(conds(i)) {
result := i
}
ctx.otherwise{
result := 255
} => assign when_Utils_l1437 = conds[0];
always @(*) begin
if(when_Utils_l1437) begin
result = 8'h0;
end else begin
if(when_Utils_l1440) begin
result = 8'h01;
end else begin
if(when_Utils_l1440_1) begin
result = 8'h02;
end else begin
if(when_Utils_l1440_2) begin
result = 8'h03;
end else begin
if(when_Utils_l1440_3) begin
result = 8'h05;
end else begin
if(when_Utils_l1440_4) begin
result = 8'h06;
end else begin
if(when_Utils_l1440_5) begin
result = 8'h07;
end else begin
result = 8'hff;
end
end
end
end
end
end
end
end
assign when_Utils_l1440 = conds[1];
assign when_Utils_l1440_1 = conds[2];
assign when_Utils_l1440_2 = conds[3];
assign when_Utils_l1440_3 = conds[5];
assign when_Utils_l1440_4 = conds[6];
assign when_Utils_l1440_5 = conds[7]; More syntax suggars can be added Would this match the need ? |
@Dolu1990 Good, this meets my need for parameterization. It's indeed a feature that's not easy to discover, so it's necessary to add it to the documentation. |
Yes i agree, this is quite underground lacking doc. |
@Dolu1990 don't worry, I will add it to the document later. i have another question , Is there a way to move the previous expression to the later , some thing like this , //#PART1
when(io.addr === 0x0004 && io.wr){
my_reg := io.wdata
}.elsewhen(io.clr){
my_reg := B(0x1234, 32 bit)
}
...
...
...
i know my_reg have many method like `my_reg.removeStatement(`)
did there have mothod to get `my_reg.getStatement()` then move to another place
//#PART2
when(io.set){
my_reg := B(0x1234, 32 bit)
}.elewhen(xxxx){
my_reg.move_part1_logic_to_here
}.otherwise{
my_reg := B(0x0000, 32 bit)
} Of course, this feature is not recommended for ordinary users to use, but it is still necessary to reserve such interfaces for areas that require hacks. |
Thanks :D
So, moving things using my_reg as "anchor" is tricky , because it would not be realy a move, but more a "move statments into a duplicated conditional scope". I would say that instead, moving the whole when statements would be easier, but there is nothing in place for this yet. But it would just be about patching the linkedlist of statements i think. But there may be some tricky side effects related to statements ordering, i'm not sure. Otherwise : def func(){
when(io.addr === 0x0004 && io.wr){
my_reg := io.wdata
}.elsewhen(io.clr){
my_reg := B(0x1234, 32 bit)
}
}
//#PART2
when(io.set){
my_reg := B(0x1234, 32 bit)
}.elewhen(xxxx){
func()
}.otherwise{
my_reg := B(0x0000, 32 bit)
} |
Indeed, it might not be easy to handle, and it could be more feasible to choose a |
@Dolu1990 Can we add another way as an expression for a priority circuit, called
cascad
cascad{ cond(cond0){...} cond(cond1){...} cond(cond2){...} default() //"default" is necessary in combinational logic but optional in sequential logic. }
got verilog
Compared to the
when/elsewhen/otherwise
approach, it might be more convenient for parameterization. Previously, I had to use multiplewhen
statements and their order to achieve priority. The code it generates would also consist of multiple parallelif()
statements, prioritized based on the order of 'if()'. For typical Verilog code, this approach doesn't always align well with development habits.got verilog
This way, we can parameterize priority circuits similar to how we use 'foreach' inside 'switch()', and generate code in a more intuitive if-else format.
now we can expresion priroty code like this
Of course, the
when/elsewhen/otherwise
approach also has its place. For certain fixed code structures, this method is more intuitive and aligns better with Verilog writing conventions.Now we have an additional way to represent priority circuits called 'cascade', rather than replacing the original 'when/elsewhen' approach.
The text was updated successfully, but these errors were encountered: