veryl-lang / veryl Goto Github PK
View Code? Open in Web Editor NEWVeryl: A Modern Hardware Description Language
License: Other
Veryl: A Modern Hardware Description Language
License: Other
always_comb {
a = if x > 1 {
b
} else {
c
};
}
like var a: tri u32;
Is there any usege?
package PackageA {
var memberA: u32;
}
variable declaration and assign declaration seems to be similar. It may be confusable.
Additionally, visilibity of variable declaration may be less than other declarations because it doesn't have any keyword.
// variable declaration
a: logic [10];
// assign declaration
assign a = 1;
// assign declaration with type
assign a: logic [10] = 1;
Alternative idea.
// variable declaration
let a: logic [10];
// variable declaration with binding
let a: logic [10] = 1;
import PackageA::Item;
import PackageB::*;
module's import like below causes parsing and formatting complexity.
module ModuleA import PackageA::* (
) {
}
Instead of supporting module's import, is it sufficient like below?
import PackageA::*;
module ModuleA (
) {
}
The current syntax is below:
b ::: ModuleB #(
// parameter override
} {
// port connection
}
The reason of :::
is
:
is the same as variable declaration::
is the same as name space path separatorIf let
like #7 is introduced, :
can be used.
Or keyword is good?
inst b : ModuleB #(
) {
}
always_ff (clk) {
case x {
0: a = 1;
1: a = 2;
2: {
a = 3;
b = 4;
}
default: a = 4;
}
}
The veryl build
command generates SV code even if an enum value is outrange.
orignal VL code:
module test {
enum e_foo_bar: logic [1] {
foo = 0,
bar = 2
}
}
generated SV code:
module test ;
typedef enum logic [1-1:0] {
foo = 0,
bar = 2
} e_foo_bar;
endmodule
The verly command needs to check range of enum values because this causes a compile error.
Error-[ENUMRANGE] Enum label outside value range
testbench.sv, 7
The enum label 'BAR' has the value 2 which is outside the range of the base
type of the enum 'e_foo_bar', which is 1 bit unsigned.
If this is indeed the intended value, consider expressing it as as sized
literal of the same width and signedness as the enum base type.
The build commmand genertes illegal SV code from VL code with comments.
These comments are put:
These are an exaple code and generated SV code:
module test_module (
i_clk: input logic,
i_rst_n: input logic,
i_up: input logic,
i_down: input logic,
o_count: output logic[8]
) {
count: logic[8];
up_down: logic[2];
always_comb {
up_down = (i_up << 1) | i_down;
}
always_ff (i_clk, i_rst_n) {
if_reset {
count = 0;
}
else // count up
if up_down == 2'b10 {
count = count + 1;
}
else if // count down
up_down == 2'b01 {
count = count - 1;
}
}
}
module test_module (
input logic i_clk ,
input logic i_rst_n,
input logic i_up ,
input logic i_down ,
output logic [8-1:0] o_count
) ;
logic [8-1:0] count ;
logic [2-1:0] up_down;
always_comb begin
up_down = (i_up << 1) | i_down;
end
always_ff @ (posedge i_clk, negedge i_rst_n) begin
if (!i_rst_n) begin
count <= 0;
end else // count up if (up_down == 2'b10) begin
count <= count + 1;
end else if // count down (up_down == 2'b01) begin
count <= count - 1;
end
end
endmodule
if (up_down == 2'b10) begin
and (up_down == 2'b01) begin
are hidden because they are comments.
I think /* */
comment format should be used for inserted comments.
SystemVerilog has useful sytem functions, such as $clog2
.
I'd like to use SV system functions within VL code but I got a syntax error.
Error: parol_runtime::unexpected_token
× Unexpected token: LA(1) (Error)
╭─[test.vl:3:1]
3 │ parameter MAX_COUNT: u32 = 8,
4 │ parameter COUNT_WIDTH: u32 = $clog2(MAX_COUNT + 1)
· ┬
· ╰── Unexpected token
5 │ )(
╰────
help: Unexpected token
Does not support such feature?
:label {
}
This is converted to
if (1) begin :label
end
https://zenn.dev/link/comments/bc4a82a9776d86
SystemVerilog representation should be considered.
The current syntax error is from parol's error.
It may not be suitable with language server.
I got a problem that veryl build
command does not report a error when parsing VL code including a syntax error.
How to reproduce:
Run veryl build
command with following VL code.
module test_module (
i_clk: input logic,
i_rst_n: input logic,
i_d: input logic,
o_d: output logic
) {
d: logic;
always_comb {
o_d = d;
}
always_ff (i_clk, i_rst_n) {
if_rest {
d = 0;
}
else {
d = i_d;
}
}
}
I expect the command reports a syntax error because there is a typo (if_reset -> if_rest).
But the command completes SV code generation.
let statement for variable declaration and module/interface instantiation.
// variable declaration
let value_a: logic [10];
// assignment after declaration
assgin value_a = 1;
// variable declaration with assignment
let value_b: logic [10] = 1;
// module instantiation
let module_a: inst moduleA;
// interface instantiation
let if_a: inst interfaceA;
// interface array
let if_b: inst interfaceB [10];
// module with parameter and port connection
let module_b: inst moduleB #(
a,
b: 10,
) {
a,
b: 10,
};
The definition will contain..
My existing SV code includes loop statements such as for loop and while loop so I'd like Veryl to support these statements.
I think SV (C lang) style for loop statement is very bother notation because there are many similar code for example int i = 0;
and ++i;
. So I'd like you to introduce simple notation.
accessing to interface item / modport / module inner item
For example, port variable will be highlighted.
Now ::
and .
are used as identifier separator.
import PackageA::A;
module ModuleA (
a: input PackageA::struct_t,
b: modport InterfaceA.master,
) {
assign a.memberA = b.funcA(1);
assign b.portA = PackageA::parameterA;
}
Almost .
is used for [instance/variable identifier].[member identifier]
and ::
is used for [type/definition identifier]::[member identifier]
.
But InterfaceA.master
seems to be inconsistent.
How about InterfaceA::master
? and is there another case?
import PackageA::A;
module ModuleA (
a: input PackageA::struct_t,
b: modport InterfaceA::master,
) {
assign a.memberA = b.funcA(1);
assign b.portA = PackageA::parameterA;
}
Is adding modport
in port declaration of module declaration more explicit?
module ModuleA (
a: input logic,
b: output logic,
c: modport InterfaceA.master,
) {
}
Part select using position and width (a[pos+:WIDTH]
/a[pos-:WIDTH]
) is useful feature.
So I'd like you to import this feature to veryl.
In addition, I think part select using index and width like below is a code showing often.
b = a[2*i+:2];
Therefore, I'd like you to introduce a syntax sugger for this code like below.
b = a[2, i]; // a[2*i+:2]
SystemVerilog don't allow variable forward reference.
It causes distributed variable declarations which are included in the same group.
// Move the declaration to the top of code to avoid forward reference
let b2: logic;
// Module A
let a0: logic = b2 + 1;
// Module B
let b0: logic;
let b1: logic;
// let b2: logic <- This position is suitable
Unlike general programming language, RTL don't have code order.
So variable forward reference is natural in RTL.
Inserting type cast is needed when LHS of assignment is enum variable and RHS of assignment is non-enum value.
If no type cast is inserted then EDA tool may report a warning like below.
Warning-[ENUMASSIGN] Illegal assignment to enum variable
testbench.sv, 13
test, "foo_bar = 0;"
Only expressions of the enum type can be assigned to an enum variable.
The type int is incompatible with the enum 'e_foo_bar'
Expression: 0
Use the static cast operator to convert the expression to enum type.
However generated SV code does not include type cast.
orignal VL code:
module test {
enum e_foo_bar: logic [1] {
foo = 0,
bar = 1
}
let foo_bar: e_foo_bar;
always_comb {
foo_bar = foo;
foo_bar = bar;
foo_bar = 0;
foo_bar = 1;
}
}
generated SV code:
module test ;
typedef enum logic [1-1:0] {
foo = 0,
bar = 1
} e_foo_bar;
e_foo_bar foo_bar ;
always_comb begin
foo_bar = foo;
foo_bar = bar;
foo_bar = 0;
foo_bar = 1;
end
endmodule
I think in Varyl tri
keyword is used as a data type.
On the other hand, in SystemVerilog the tri
keyword is used to show that a declared element is a wire and to allow the element to have multiple drivers. Therefore, its usage is similar to the usage of the var
keyword.
package foo_pkg;
typedef enum logic {
FOO_0,
FOO_1
} e_foo;
endpackage
module foo_sub
import foo_pkg::*;
(
inout tri e_foo io_foo
);
assign io_foo = FOO_0;
endmodule
module foo_top;
import foo_pkg::*;
tri e_foo foo;
assign foo = FOO_1;
foo_sub u_sub (foo);
endmodule
I think Veryl should also use the tri
like the var
keyword.
This is required for #47
Verilog style
assign a = {x, 1'b1, y[10:0]};
assign a = {{10{x}}, {10{y}}};
Repeat style has some problems.
{}
To resolve the second, repeating number should be after repeating operator.
Repeating operator should be keyword or symbol?
assign = a { x repeat 10, y repeat 10};
assign = a { x @ 10, y @ 10};
msb
is expanded BIT_WIDTH-1
.
always_comb {
a = x[msb:8];
b = x[10:lsb]; // lsb is the same as 0
}
If there are parameter declarations in module dispersedly, user of module can't find overridable paramaters easily.
module #(
parameter A: u32 = 1,
) {
localparam C: u32 = 1;
// some descriptions...
parameter B: u32 = 1; // <- forbid This
}
Currently, the following code causes duplicated identifier error.
Each claure of if declaration should have independent scope.
if a ==1 :label {
let a: logic;
} else {
let a: logic;
}
to avoid name conflict between packages
Some semantic check like bit width check requires parameter evaluation.
include #29
For example, completing module instantiation with port.
Removing () in always_ff is uniform as if
statement.
always_ff (clk) {
}
always_ff (clk, rst) {
}
always_ff (posedge clk, async_low rst) {
}
to
always_ff clk {
}
always_ff clk, rst {
}
always_ff posedge clk, async_low rst {
}
enum member of SystemVerilog has the same scope of the enum.
enum EnumA {
memberA,
memberB,
}
var a: EnumA = memberA;
This causes name conflict easily.
How about EnumA::memberA
.
enum EnumA: logic {
memberA,
memberB,
}
var a: EnumA = EnumA::memberA;
In translated SystemVerilog, prefix is added to avoid conflict.
typedef enum logic {
EnumA_memberA,
EnumA_memberB,
} EnumA;
EnumA a;
assign a = EnumA_memberA;
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.