Skip to content

Commit 86ee6c7

Browse files
committed
Allow out port in sensitivity list
1 parent dc48697 commit 86ee6c7

File tree

7 files changed

+82
-115
lines changed

7 files changed

+82
-115
lines changed

vhdl_lang/src/analysis/concurrent.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,8 @@ impl<'a> AnalyzeContext<'a> {
335335
object_name.base.describe_class()
336336
),
337337
)
338-
} else if object_name.base.mode() == Some(Mode::Out) {
338+
} else if object_name.base.mode() == Some(Mode::Out) && !object_name.base.is_port()
339+
{
339340
diagnostics.error(
340341
&name.pos,
341342
format!(

vhdl_lang/src/analysis/declarative.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ impl<'a> AnalyzeContext<'a> {
271271
} else {
272272
AnyEntKind::Object(Object {
273273
class: object_decl.class,
274+
is_port: false,
274275
mode: None,
275276
has_default: object_decl.expression.is_some(),
276277
subtype,
@@ -1113,6 +1114,7 @@ impl<'a> AnalyzeContext<'a> {
11131114
&mut object_decl.ident,
11141115
AnyEntKind::Object(Object {
11151116
class: object_decl.class,
1117+
is_port: object_decl.list_type == InterfaceListType::Port,
11161118
mode: Some(object_decl.mode),
11171119
subtype,
11181120
has_default: object_decl.expression.is_some(),

vhdl_lang/src/analysis/named_entity/object.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,29 @@ impl<'a> ObjectEnt<'a> {
8181
#[derive(Clone)]
8282
pub struct Object<'a> {
8383
pub class: ObjectClass,
84+
pub is_port: bool,
8485
pub mode: Option<Mode>,
8586
pub subtype: Subtype<'a>,
8687
pub has_default: bool,
8788
}
8889

90+
impl<'a> Object<'a> {
91+
pub(crate) fn if_constant(subtype: Subtype<'a>) -> Object<'a> {
92+
Object {
93+
class: ObjectClass::Constant,
94+
is_port: false,
95+
mode: Some(Mode::In),
96+
subtype,
97+
has_default: false,
98+
}
99+
}
100+
101+
pub(crate) fn with_default(mut self) -> Self {
102+
self.has_default = true;
103+
self
104+
}
105+
}
106+
89107
impl ObjectClass {
90108
pub fn describe(&self) -> &str {
91109
use ObjectClass::*;

vhdl_lang/src/analysis/names.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ impl<'a> ObjectBase<'a> {
6868
}
6969
}
7070
}
71+
72+
pub fn is_port(&self) -> bool {
73+
match self {
74+
ObjectBase::Object(obj) => obj.kind().is_port,
75+
ObjectBase::ObjectAlias(obj, _) => obj.kind().is_port,
76+
ObjectBase::DeferredConstant(_) => false,
77+
ObjectBase::ExternalName(_) => false,
78+
}
79+
}
7180
}
7281

7382
#[derive(Debug, Copy, Clone, PartialEq, Eq)]

vhdl_lang/src/analysis/package_instance.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,13 +513,15 @@ impl<'a> AnalyzeContext<'a> {
513513
) -> Result<Object<'a>, String> {
514514
let Object {
515515
class,
516+
is_port,
516517
mode,
517518
subtype,
518519
has_default,
519520
} = obj;
520521

521522
Ok(Object {
522523
class: *class,
524+
is_port: *is_port,
523525
mode: *mode,
524526
subtype: self.map_subtype(mapping, *subtype)?,
525527
has_default: *has_default,

vhdl_lang/src/analysis/standard.rs

Lines changed: 26 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -238,23 +238,13 @@ impl<'a> AnalyzeContext<'a> {
238238
let mut formals = FormalRegion::new_params();
239239
formals.add(self.arena.explicit(
240240
self.symbol("L"),
241-
AnyEntKind::Object(Object {
242-
class: ObjectClass::Constant,
243-
mode: Some(Mode::In),
244-
subtype: Subtype::new(type_ent),
245-
has_default: false,
246-
}),
241+
AnyEntKind::Object(Object::if_constant(Subtype::new(type_ent))),
247242
type_ent.decl_pos(),
248243
));
249244

250245
formals.add(self.arena.explicit(
251246
self.symbol("R"),
252-
AnyEntKind::Object(Object {
253-
class: ObjectClass::Constant,
254-
mode: Some(Mode::In),
255-
subtype: Subtype::new(type_ent),
256-
has_default: false,
257-
}),
247+
AnyEntKind::Object(Object::if_constant(Subtype::new(type_ent))),
258248
type_ent.decl_pos(),
259249
));
260250

@@ -275,12 +265,7 @@ impl<'a> AnalyzeContext<'a> {
275265
let mut formals = FormalRegion::new_params();
276266
formals.add(self.arena.explicit(
277267
self.symbol("L"),
278-
AnyEntKind::Object(Object {
279-
class: ObjectClass::Constant,
280-
mode: Some(Mode::In),
281-
subtype: Subtype::new(arr_typ),
282-
has_default: false,
283-
}),
268+
AnyEntKind::Object(Object::if_constant(Subtype::new(arr_typ))),
284269
arr_typ.decl_pos(),
285270
));
286271

@@ -297,12 +282,7 @@ impl<'a> AnalyzeContext<'a> {
297282
formals.add(self.arena.explicit(
298283
// @TODO anonymous
299284
self.symbol("V"),
300-
AnyEntKind::Object(Object {
301-
class: ObjectClass::Constant,
302-
mode: Some(Mode::In),
303-
subtype: Subtype::new(typ.to_owned()),
304-
has_default: false,
305-
}),
285+
AnyEntKind::Object(Object::if_constant(Subtype::new(typ))),
306286
typ.decl_pos(),
307287
));
308288

@@ -331,24 +311,14 @@ impl<'a> AnalyzeContext<'a> {
331311
formals.add(self.arena.explicit(
332312
// @TODO anonymous
333313
self.symbol("L"),
334-
AnyEntKind::Object(Object {
335-
class: ObjectClass::Constant,
336-
mode: Some(Mode::In),
337-
subtype: Subtype::new(left),
338-
has_default: false,
339-
}),
314+
AnyEntKind::Object(Object::if_constant(Subtype::new(left))),
340315
implicit_of.decl_pos(),
341316
));
342317

343318
formals.add(self.arena.explicit(
344319
// @TODO anonymous
345320
self.symbol("R"),
346-
AnyEntKind::Object(Object {
347-
class: ObjectClass::Constant,
348-
mode: Some(Mode::In),
349-
subtype: Subtype::new(right),
350-
has_default: false,
351-
}),
321+
AnyEntKind::Object(Object::if_constant(Subtype::new(right))),
352322
implicit_of.decl_pos(),
353323
));
354324

@@ -394,23 +364,15 @@ impl<'a> AnalyzeContext<'a> {
394364
));
395365
formals.add(self.arena.explicit(
396366
self.symbol("External_Name"),
397-
AnyEntKind::Object(Object {
398-
class: ObjectClass::Constant,
399-
mode: Some(Mode::In),
400-
subtype: Subtype::new(string),
401-
has_default: false,
402-
}),
367+
AnyEntKind::Object(Object::if_constant(Subtype::new(string))),
403368
file_type.decl_pos(),
404369
));
405370

406371
formals.add(self.arena.explicit(
407372
self.symbol("Open_Kind"),
408-
AnyEntKind::Object(Object {
409-
class: ObjectClass::Constant,
410-
mode: Some(Mode::In),
411-
subtype: Subtype::new(file_open_kind),
412-
has_default: true,
413-
}),
373+
AnyEntKind::Object(
374+
Object::if_constant(Subtype::new(file_open_kind)).with_default(),
375+
),
414376
file_type.decl_pos(),
415377
));
416378
implicit.push(self.arena.implicit(
@@ -426,12 +388,7 @@ impl<'a> AnalyzeContext<'a> {
426388
let mut formals = FormalRegion::new_params();
427389
formals.add(self.arena.explicit(
428390
self.symbol("Status"),
429-
AnyEntKind::Object(Object {
430-
class: ObjectClass::Variable,
431-
mode: Some(Mode::Out),
432-
subtype: Subtype::new(file_open_status),
433-
has_default: false,
434-
}),
391+
AnyEntKind::Object(Object::if_constant(Subtype::new(file_open_status))),
435392
file_type.decl_pos(),
436393
));
437394
formals.add(self.arena.explicit(
@@ -441,23 +398,15 @@ impl<'a> AnalyzeContext<'a> {
441398
));
442399
formals.add(self.arena.explicit(
443400
self.symbol("External_Name"),
444-
AnyEntKind::Object(Object {
445-
class: ObjectClass::Constant,
446-
mode: Some(Mode::In),
447-
subtype: Subtype::new(string),
448-
has_default: false,
449-
}),
401+
AnyEntKind::Object(Object::if_constant(Subtype::new(string))),
450402
file_type.decl_pos(),
451403
));
452404

453405
formals.add(self.arena.explicit(
454406
self.symbol("Open_Kind"),
455-
AnyEntKind::Object(Object {
456-
class: ObjectClass::Constant,
457-
mode: Some(Mode::In),
458-
subtype: Subtype::new(file_open_kind),
459-
has_default: true,
460-
}),
407+
AnyEntKind::Object(
408+
Object::if_constant(Subtype::new(file_open_kind)).with_default(),
409+
),
461410
file_type.decl_pos(),
462411
));
463412
implicit.push(self.arena.implicit(
@@ -498,6 +447,7 @@ impl<'a> AnalyzeContext<'a> {
498447
self.symbol("VALUE"),
499448
AnyEntKind::Object(Object {
500449
class: ObjectClass::Variable,
450+
is_port: false,
501451
mode: Some(Mode::Out),
502452
subtype: Subtype::new(type_mark),
503453
has_default: false,
@@ -524,12 +474,7 @@ impl<'a> AnalyzeContext<'a> {
524474

525475
formals.add(self.arena.explicit(
526476
self.symbol("VALUE"),
527-
AnyEntKind::Object(Object {
528-
class: ObjectClass::Constant,
529-
mode: Some(Mode::In),
530-
subtype: Subtype::new(type_mark),
531-
has_default: false,
532-
}),
477+
AnyEntKind::Object(Object::if_constant(Subtype::new(type_mark))),
533478
file_type.decl_pos(),
534479
));
535480

@@ -584,12 +529,7 @@ impl<'a> AnalyzeContext<'a> {
584529
let mut formals = FormalRegion::new_params();
585530
formals.add(self.arena.explicit(
586531
self.symbol("VALUE"),
587-
AnyEntKind::Object(Object {
588-
class: ObjectClass::Constant,
589-
mode: Some(Mode::In),
590-
subtype: Subtype::new(type_ent),
591-
has_default: false,
592-
}),
532+
AnyEntKind::Object(Object::if_constant(Subtype::new(type_ent))),
593533
type_ent.decl_pos(),
594534
));
595535

@@ -607,12 +547,7 @@ impl<'a> AnalyzeContext<'a> {
607547
let mut formals = FormalRegion::new_params();
608548
formals.add(self.arena.explicit(
609549
self.symbol("VALUE"),
610-
AnyEntKind::Object(Object {
611-
class: ObjectClass::Constant,
612-
mode: Some(Mode::In),
613-
subtype: Subtype::new(type_ent),
614-
has_default: false,
615-
}),
550+
AnyEntKind::Object(Object::if_constant(Subtype::new(type_ent))),
616551
type_ent.decl_pos(),
617552
));
618553

@@ -632,6 +567,7 @@ impl<'a> AnalyzeContext<'a> {
632567
self.symbol("P"),
633568
AnyEntKind::Object(Object {
634569
class: ObjectClass::Variable,
570+
is_port: false,
635571
mode: Some(Mode::InOut),
636572
subtype: Subtype::new(type_ent.to_owned()),
637573
has_default: false,
@@ -1032,6 +968,7 @@ impl<'a> AnalyzeContext<'a> {
1032968
self.symbol("VALUE"),
1033969
AnyEntKind::Object(Object {
1034970
class: ObjectClass::Constant,
971+
is_port: false,
1035972
mode: Some(Mode::In),
1036973
subtype: Subtype::new(real.to_owned()),
1037974
has_default: false,
@@ -1041,12 +978,7 @@ impl<'a> AnalyzeContext<'a> {
1041978

1042979
formals.add(self.arena.explicit(
1043980
self.symbol("DIGITS"),
1044-
AnyEntKind::Object(Object {
1045-
class: ObjectClass::Constant,
1046-
mode: Some(Mode::In),
1047-
subtype: Subtype::new(natural),
1048-
has_default: false,
1049-
}),
981+
AnyEntKind::Object(Object::if_constant(Subtype::new(natural))),
1050982
real.decl_pos(),
1051983
));
1052984

@@ -1072,23 +1004,13 @@ impl<'a> AnalyzeContext<'a> {
10721004
let mut formals = FormalRegion::new_params();
10731005
formals.add(self.arena.explicit(
10741006
self.symbol("VALUE"),
1075-
AnyEntKind::Object(Object {
1076-
class: ObjectClass::Constant,
1077-
mode: Some(Mode::In),
1078-
subtype: Subtype::new(real.to_owned()),
1079-
has_default: false,
1080-
}),
1007+
AnyEntKind::Object(Object::if_constant(Subtype::new(real))),
10811008
real.decl_pos(),
10821009
));
10831010

10841011
formals.add(self.arena.explicit(
10851012
self.symbol("FORMAT"),
1086-
AnyEntKind::Object(Object {
1087-
class: ObjectClass::Constant,
1088-
mode: Some(Mode::In),
1089-
subtype: Subtype::new(string.to_owned()),
1090-
has_default: false,
1091-
}),
1013+
AnyEntKind::Object(Object::if_constant(Subtype::new(string))),
10921014
real.decl_pos(),
10931015
));
10941016

@@ -1113,23 +1035,13 @@ impl<'a> AnalyzeContext<'a> {
11131035
let mut formals = FormalRegion::new_params();
11141036
formals.add(self.arena.explicit(
11151037
self.symbol("VALUE"),
1116-
AnyEntKind::Object(Object {
1117-
class: ObjectClass::Constant,
1118-
mode: Some(Mode::In),
1119-
subtype: Subtype::new(time.to_owned()),
1120-
has_default: false,
1121-
}),
1038+
AnyEntKind::Object(Object::if_constant(Subtype::new(time))),
11221039
time.decl_pos(),
11231040
));
11241041

11251042
formals.add(self.arena.explicit(
11261043
self.symbol("UNIT"),
1127-
AnyEntKind::Object(Object {
1128-
class: ObjectClass::Constant,
1129-
mode: Some(Mode::In),
1130-
subtype: Subtype::new(time.to_owned()),
1131-
has_default: false,
1132-
}),
1044+
AnyEntKind::Object(Object::if_constant(Subtype::new(time))),
11331045
time.decl_pos(),
11341046
));
11351047

vhdl_lang/src/analysis/tests/sensitivity_list.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,26 @@ end package body;
9292
)],
9393
)
9494
}
95+
96+
#[test]
97+
fn may_be_output_port() {
98+
let mut builder = LibraryBuilder::new();
99+
builder.code(
100+
"libname",
101+
"
102+
entity ent is
103+
port (oport : out bit);
104+
end entity;
105+
106+
architecture a of ent is
107+
begin
108+
main: process (oport)
109+
begin
110+
end process main;
111+
end architecture;
112+
113+
",
114+
);
115+
let (_, diagnostics) = builder.get_analyzed_root();
116+
check_no_diagnostics(&diagnostics);
117+
}

0 commit comments

Comments
 (0)