Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/analyzer/src/handlers/check_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ fn check_generic_type_arg(
namespace: &Namespace,
base: &Symbol,
) -> Option<AnalyzerError> {
if matches!(arg.kind, GenericSymbolPathKind::FixedType) {
if matches!(arg.kind, GenericSymbolPathKind::FixedType(_)) {
None
} else if arg.is_resolvable() {
let Ok(symbol) = symbol_table::resolve((&arg.generic_path(), namespace)) else {
Expand Down
174 changes: 154 additions & 20 deletions crates/analyzer/src/symbol_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,157 @@ impl From<(&GenericSymbolPath, &Namespace)> for GenericSymbolPathNamesapce {
}
}

#[derive(Copy, Debug, Clone, PartialEq, Eq)]
pub enum FixedTypeKind {
U8,
U16,
U32,
U64,
I8,
I16,
I32,
I64,
F32,
F64,
Bool,
String,
}

impl fmt::Display for FixedTypeKind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let text = match self {
Self::U8 => "u8",
Self::U16 => "u16",
Self::U32 => "u32",
Self::U64 => "u64",
Self::I8 => "i8",
Self::I16 => "i16",
Self::I32 => "i32",
Self::I64 => "i64",
Self::F32 => "f32",
Self::F64 => "f64",
Self::Bool => "bool",
Self::String => "string",
};
text.fmt(f)
}
}

impl FixedTypeKind {
pub fn to_sv_string(&self) -> String {
let text = match self {
Self::U8 => "byte unsigned",
Self::U16 => "shortint unsigned",
Self::U32 => "int unsigned",
Self::U64 => "longint unsigned",
Self::I8 => "byte signed",
Self::I16 => "shortint signed",
Self::I32 => "int signed",
Self::I64 => "longint signed",
Self::F32 => "shortreal",
Self::F64 => "real",
Self::Bool => "logic",
Self::String => "string",
};
text.to_string()
}
}

impl From<&syntax_tree::U8> for FixedTypeKind {
fn from(_value: &syntax_tree::U8) -> Self {
Self::U8
}
}

impl From<&syntax_tree::U16> for FixedTypeKind {
fn from(_value: &syntax_tree::U16) -> Self {
Self::U16
}
}

impl From<&syntax_tree::U32> for FixedTypeKind {
fn from(_value: &syntax_tree::U32) -> Self {
Self::U32
}
}

impl From<&syntax_tree::U64> for FixedTypeKind {
fn from(_value: &syntax_tree::U64) -> Self {
Self::U64
}
}

impl From<&syntax_tree::I8> for FixedTypeKind {
fn from(_value: &syntax_tree::I8) -> Self {
Self::I8
}
}

impl From<&syntax_tree::I16> for FixedTypeKind {
fn from(_value: &syntax_tree::I16) -> Self {
Self::I16
}
}

impl From<&syntax_tree::I32> for FixedTypeKind {
fn from(_value: &syntax_tree::I32) -> Self {
Self::I32
}
}

impl From<&syntax_tree::I64> for FixedTypeKind {
fn from(_value: &syntax_tree::I64) -> Self {
Self::I64
}
}

impl From<&syntax_tree::F32> for FixedTypeKind {
fn from(_value: &syntax_tree::F32) -> Self {
Self::F32
}
}

impl From<&syntax_tree::F64> for FixedTypeKind {
fn from(_value: &syntax_tree::F64) -> Self {
Self::F64
}
}

impl From<&syntax_tree::Bool> for FixedTypeKind {
fn from(_value: &syntax_tree::Bool) -> Self {
Self::Bool
}
}

impl From<&syntax_tree::Strin> for FixedTypeKind {
fn from(_value: &syntax_tree::Strin) -> Self {
Self::String
}
}

impl From<&syntax_tree::FixedType> for FixedTypeKind {
fn from(value: &syntax_tree::FixedType) -> Self {
match value {
syntax_tree::FixedType::U8(x) => x.u8.as_ref().into(),
syntax_tree::FixedType::U16(x) => x.u16.as_ref().into(),
syntax_tree::FixedType::U32(x) => x.u32.as_ref().into(),
syntax_tree::FixedType::U64(x) => x.u64.as_ref().into(),
syntax_tree::FixedType::I8(x) => x.i8.as_ref().into(),
syntax_tree::FixedType::I16(x) => x.i16.as_ref().into(),
syntax_tree::FixedType::I32(x) => x.i32.as_ref().into(),
syntax_tree::FixedType::I64(x) => x.i64.as_ref().into(),
syntax_tree::FixedType::F32(x) => x.f32.as_ref().into(),
syntax_tree::FixedType::F64(x) => x.f64.as_ref().into(),
syntax_tree::FixedType::Bool(x) => x.bool.as_ref().into(),
syntax_tree::FixedType::Strin(x) => x.strin.as_ref().into(),
}
}
}

#[derive(Copy, Debug, Clone, PartialEq, Eq)]
pub enum GenericSymbolPathKind {
Identifier,
FixedType,
FixedType(FixedTypeKind),
IntegerBased,
IntegerBaseLess,
IntegerAllBit,
Expand All @@ -272,7 +419,7 @@ impl fmt::Display for GenericSymbolPathKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let text = match self {
GenericSymbolPathKind::Identifier => "identifier".to_string(),
GenericSymbolPathKind::FixedType => "fixed type".to_string(),
GenericSymbolPathKind::FixedType(x) => x.to_string(),
GenericSymbolPathKind::IntegerBased => "integer based".to_string(),
GenericSymbolPathKind::IntegerBaseLess => "integer base less".to_string(),
GenericSymbolPathKind::IntegerAllBit => "integer all bit".to_string(),
Expand Down Expand Up @@ -658,28 +805,15 @@ impl From<&Token> for GenericSymbolPath {

impl From<&syntax_tree::FixedType> for GenericSymbolPath {
fn from(value: &syntax_tree::FixedType) -> Self {
let token = match value {
syntax_tree::FixedType::U8(x) => x.u8.u8_token.token,
syntax_tree::FixedType::U16(x) => x.u16.u16_token.token,
syntax_tree::FixedType::U32(x) => x.u32.u32_token.token,
syntax_tree::FixedType::U64(x) => x.u64.u64_token.token,
syntax_tree::FixedType::I8(x) => x.i8.i8_token.token,
syntax_tree::FixedType::I16(x) => x.i16.i16_token.token,
syntax_tree::FixedType::I32(x) => x.i32.i32_token.token,
syntax_tree::FixedType::I64(x) => x.i64.i64_token.token,
syntax_tree::FixedType::F32(x) => x.f32.f32_token.token,
syntax_tree::FixedType::F64(x) => x.f64.f64_token.token,
syntax_tree::FixedType::Bool(x) => x.bool.bool_token.token,
syntax_tree::FixedType::Strin(x) => x.strin.string_token.token,
};

let token: TokenRange = value.into();
let kind: FixedTypeKind = value.into();
GenericSymbolPath {
paths: vec![GenericSymbol {
base: token,
base: token.beg,
arguments: Vec::new(),
}],
kind: GenericSymbolPathKind::FixedType,
range: token.into(),
kind: GenericSymbolPathKind::FixedType(kind),
range: token,
}
}
}
Expand Down
51 changes: 35 additions & 16 deletions crates/emitter/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use veryl_analyzer::symbol::TypeModifierKind as SymTypeModifierKind;
use veryl_analyzer::symbol::{
GenericMap, GenericTables, Port, Symbol, SymbolId, SymbolKind, TypeKind, VariableAffiliation,
};
use veryl_analyzer::symbol_path::{GenericSymbolPath, GenericSymbolPathKind, SymbolPath};
use veryl_analyzer::symbol_path::{
FixedTypeKind, GenericSymbolPath, GenericSymbolPathKind, SymbolPath,
};
use veryl_analyzer::symbol_table::{self, ResolveError, ResolveResult};
use veryl_analyzer::{msb_table, namespace_table};
use veryl_metadata::{Build, BuiltinType, ClockType, Format, Metadata, ResetType, SourceMapTarget};
Expand Down Expand Up @@ -2176,7 +2178,8 @@ impl VerylWalker for Emitter {

/// Semantic action for non-terminal 'Bool'
fn bool(&mut self, arg: &Bool) {
self.veryl_token(&arg.bool_token.replace("logic"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.bool_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'Clock'
Expand Down Expand Up @@ -2226,12 +2229,14 @@ impl VerylWalker for Emitter {

/// Semantic action for non-terminal 'F32'
fn f32(&mut self, arg: &F32) {
self.veryl_token(&arg.f32_token.replace("shortreal"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.f32_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'F64'
fn f64(&mut self, arg: &F64) {
self.veryl_token(&arg.f64_token.replace("real"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.f64_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'False'
Expand All @@ -2241,22 +2246,26 @@ impl VerylWalker for Emitter {

/// Semantic action for non-terminal 'I8'
fn i8(&mut self, arg: &I8) {
self.veryl_token(&arg.i8_token.replace("byte signed"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.i8_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'I16'
fn i16(&mut self, arg: &I16) {
self.veryl_token(&arg.i16_token.replace("shortint signed"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.i16_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'I32'
fn i32(&mut self, arg: &I32) {
self.veryl_token(&arg.i32_token.replace("int signed"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.i32_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'I64'
fn i64(&mut self, arg: &I64) {
self.veryl_token(&arg.i64_token.replace("longint signed"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.i64_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'Lsb'
Expand Down Expand Up @@ -2294,22 +2303,26 @@ impl VerylWalker for Emitter {

/// Semantic action for non-terminal 'U8'
fn u8(&mut self, arg: &U8) {
self.veryl_token(&arg.u8_token.replace("byte unsigned"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.u8_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'U16'
fn u16(&mut self, arg: &U16) {
self.veryl_token(&arg.u16_token.replace("shortint unsigned"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.u16_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'U32'
fn u32(&mut self, arg: &U32) {
self.veryl_token(&arg.u32_token.replace("int unsigned"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.u32_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'U64'
fn u64(&mut self, arg: &U64) {
self.veryl_token(&arg.u64_token.replace("longint unsigned"));
let kind: FixedTypeKind = arg.into();
self.veryl_token(&arg.u64_token.replace(&kind.to_sv_string()));
}

/// Semantic action for non-terminal 'Identifier'
Expand Down Expand Up @@ -2410,10 +2423,16 @@ impl VerylWalker for Emitter {
}
(Err(_), path) if !path.is_resolvable() => {
// emit literal by generics
let text = if let GenericSymbolPathKind::Boolean(x) = path.kind {
if x { "1'b1" } else { "1'b0" }
} else {
&path.base_path(0).0[0].to_string()
let text = match path.kind {
GenericSymbolPathKind::Boolean(x) => {
if x {
"1'b1"
} else {
"1'b0"
}
}
GenericSymbolPathKind::FixedType(x) => &x.to_sv_string(),
_ => &path.base_path(0).0[0].to_string(),
};
self.identifier(&Identifier {
identifier_token: arg.identifier().replace(text),
Expand Down
2 changes: 1 addition & 1 deletion testcases/map/57_generic_package.sv.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions testcases/sv/57_generic_package.sv
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ package veryl_testcase___Package57F__Module57F;

endpackage

package veryl_testcase___Package57G__i32;
typedef int signed TYPE;
endpackage
package veryl_testcase___Package57G__u32;
typedef int unsigned TYPE;
endpackage
package veryl_testcase___Package57G__bool;
typedef logic TYPE;
endpackage

module veryl_testcase_Module57;
import veryl_testcase_Package57E::Y;
import veryl_testcase___Package57B__5::*;
Expand All @@ -69,5 +79,9 @@ module veryl_testcase_Module57;
always_comb _d.d1 = 1;

veryl_testcase_Module57F u ();

veryl_testcase___Package57G__i32::TYPE _e; always_comb _e = 0;
veryl_testcase___Package57G__u32::TYPE _f; always_comb _f = 0;
veryl_testcase___Package57G__bool::TYPE _g; always_comb _g = 1'b0;
endmodule
//# sourceMappingURL=../map/57_generic_package.sv.map
8 changes: 8 additions & 0 deletions testcases/veryl/57_generic_package.veryl
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ package Package57F::<M: ProtoModule57F> for ProtoPackage57F {
alias module InstModule = M;
}

package Package57G::<T: type> {
type TYPE = T;
}

module Module57 {
import Package57E::Y;
import Package57B::<5>::*;
Expand All @@ -53,4 +57,8 @@ module Module57 {
assign _d.d1 = 1;

inst u: Package57F::<Module57F>::InstModule;

let _e: Package57G::<i32>::TYPE = 0;
let _f: Package57G::<u32>::TYPE = 0;
let _g: Package57G::<bool>::TYPE = false;
}