@@ -65,6 +65,52 @@ pub fn get_identifier(node: RefNode, ast: &sv_parser::SyntaxTree) -> Result<Stri
65
65
}
66
66
}
67
67
68
+ /// Parse a literal `node` in the `ast` into a boolean value
69
+ fn parse_literal_as_bool ( node : RefNode , ast : & sv_parser:: SyntaxTree ) -> Result < bool , String > {
70
+ let value = unwrap_node ! ( node, BinaryValue , HexValue , UnsignedNumber ) ;
71
+
72
+ if value. is_none ( ) {
73
+ return Err (
74
+ "Expected a BinaryValue, HexValue, or UnsignedNumber Node under the Literal"
75
+ . to_string ( ) ,
76
+ ) ;
77
+ }
78
+
79
+ match value. unwrap ( ) {
80
+ RefNode :: BinaryValue ( b) => {
81
+ let loc = b. nodes . 0 ;
82
+ let val = ast. get_str ( & loc) . unwrap ( ) ;
83
+ let num = u64:: from_str_radix ( val, 2 ) . unwrap ( ) ;
84
+ match num {
85
+ 1 => Ok ( true ) ,
86
+ 0 => Ok ( false ) ,
87
+ _ => Err ( format ! ( "Expected a 1 bit constant. Found {}" , num) ) ,
88
+ }
89
+ }
90
+ RefNode :: HexValue ( b) => {
91
+ let loc = b. nodes . 0 ;
92
+ let val = ast. get_str ( & loc) . unwrap ( ) ;
93
+ let num = u64:: from_str_radix ( val, 16 ) . unwrap ( ) ;
94
+ match num {
95
+ 1 => Ok ( true ) ,
96
+ 0 => Ok ( false ) ,
97
+ _ => Err ( format ! ( "Expected a 1 bit constant. Found {}" , num) ) ,
98
+ }
99
+ }
100
+ RefNode :: UnsignedNumber ( b) => {
101
+ let loc = b. nodes . 0 ;
102
+ let val = ast. get_str ( & loc) . unwrap ( ) ;
103
+ let num = val. parse :: < u64 > ( ) . unwrap ( ) ;
104
+ match num {
105
+ 1 => Ok ( true ) ,
106
+ 0 => Ok ( false ) ,
107
+ _ => Err ( format ! ( "Expected a 1 bit constant. Found {}" , num) ) ,
108
+ }
109
+ }
110
+ _ => unreachable ! ( ) ,
111
+ }
112
+ }
113
+
68
114
fn init_format ( program : u64 , k : usize ) -> Result < String , ( ) > {
69
115
let w = 1 << k;
70
116
match k {
@@ -633,20 +679,45 @@ impl SVModule {
633
679
. add_signal ( port_name, arg_name. unwrap ( ) ) ?;
634
680
}
635
681
None => {
636
- // Ignore clock enable and resets
682
+ // Ignore clock enable and reset signals,
683
+ // because they are not along the data path
684
+ // The verilog emitter just re-inserts them at the end
685
+ // This means we can only use D Flip-flops that are constantly *ON*.
637
686
if port_name == "CE" || port_name == "R" {
638
687
if unwrap_node ! ( arg, PrimaryLiteral ) . is_none ( ) {
639
688
return Err ( format ! (
640
- "Port {} should be driven constant" ,
689
+ "Non-data port {} should be driven constant" ,
641
690
port_name
642
691
) ) ;
643
692
}
644
- continue ;
645
693
} else {
646
- return Err ( format ! (
647
- "Expected a HierarchicalIdentifier for port {}" ,
648
- port_name
649
- ) ) ;
694
+ // If we don't have a identifier, it must be a constant connection
695
+ let arg_name = cur_insts. last ( ) . unwrap ( ) . name . clone ( )
696
+ + port_name. as_str ( )
697
+ + "_const" ;
698
+ cur_signals. push ( SVSignal :: new ( 1 , arg_name. clone ( ) ) ) ;
699
+ cur_insts
700
+ . last_mut ( )
701
+ . unwrap ( )
702
+ . add_signal ( port_name. clone ( ) , arg_name. clone ( ) ) ?;
703
+
704
+ // Create the constant
705
+ let literal = unwrap_node ! ( arg, PrimaryLiteral ) ;
706
+ if literal. is_none ( ) {
707
+ return Err ( format ! (
708
+ "Expected a literal for connection on port {}" ,
709
+ port_name
710
+ ) ) ;
711
+ }
712
+ let value = parse_literal_as_bool ( literal. unwrap ( ) , ast) ?;
713
+ let const_inst = SVPrimitive :: new_const (
714
+ value,
715
+ arg_name. clone ( ) ,
716
+ arg_name. clone ( ) + "_inst" ,
717
+ ) ;
718
+
719
+ // Insert the constant before the current instance
720
+ cur_insts. insert ( cur_insts. len ( ) - 1 , const_inst) ;
650
721
}
651
722
}
652
723
}
@@ -671,7 +742,7 @@ impl SVModule {
671
742
let lhs_id = unwrap_node ! ( lhs, Identifier ) . unwrap ( ) ;
672
743
let lhs_name = get_identifier ( lhs_id, ast) . unwrap ( ) ;
673
744
let rhs = unwrap_node ! ( net_assign, Expression ) . unwrap ( ) ;
674
- let rhs_id = unwrap_node ! ( rhs, Identifier , BinaryNumber , HexNumber ) . unwrap ( ) ;
745
+ let rhs_id = unwrap_node ! ( rhs, Identifier , PrimaryLiteral ) . unwrap ( ) ;
675
746
let assignment = unwrap_node ! ( net_assign, Symbol ) . unwrap ( ) ;
676
747
match assignment {
677
748
RefNode :: Symbol ( sym) => {
@@ -685,47 +756,20 @@ impl SVModule {
685
756
return Err ( "Expected an assignment operator" . to_string ( ) ) ;
686
757
}
687
758
}
688
- match rhs_id {
689
- RefNode :: Identifier ( _) => {
690
- let rhs_name = get_identifier ( rhs_id, ast) . unwrap ( ) ;
691
- cur_insts. push ( SVPrimitive :: new_wire (
692
- rhs_name. clone ( ) ,
693
- lhs_name. clone ( ) ,
694
- lhs_name + "_wire_" + & rhs_name,
695
- ) ) ;
696
- }
697
- RefNode :: BinaryNumber ( b) => {
698
- let loc = b. nodes . 2 . nodes . 0 ;
699
- let val = ast. get_str ( & loc) . unwrap ( ) ;
700
- let val = match val {
701
- "0" => false ,
702
- "1" => true ,
703
- _ => {
704
- return Err ( format ! (
705
- "Expected a 1 bit constant. Found {}" ,
706
- val
707
- ) ) ;
708
- }
709
- } ;
710
- cur_insts. push ( SVPrimitive :: new_const (
711
- val,
712
- lhs_name. clone ( ) ,
713
- lhs_name + "_const_binary" ,
714
- ) ) ;
715
- }
716
- RefNode :: HexNumber ( b) => {
717
- let loc = b. nodes . 2 . nodes . 0 ;
718
- let val = ast. get_str ( & loc) . unwrap ( ) ;
719
- let val = !matches ! ( val, "0" ) ;
720
- cur_insts. push ( SVPrimitive :: new_const (
721
- val,
722
- lhs_name. clone ( ) ,
723
- lhs_name + "_const_hex" ,
724
- ) ) ;
725
- }
726
- _ => {
727
- return Err ( "Expected a Identifier or PrimaryLiteral" . to_string ( ) ) ;
728
- }
759
+ if matches ! ( rhs_id, RefNode :: Identifier ( _) ) {
760
+ let rhs_name = get_identifier ( rhs_id, ast) . unwrap ( ) ;
761
+ cur_insts. push ( SVPrimitive :: new_wire (
762
+ rhs_name. clone ( ) ,
763
+ lhs_name. clone ( ) ,
764
+ lhs_name + "_wire_" + & rhs_name,
765
+ ) ) ;
766
+ } else {
767
+ let val = parse_literal_as_bool ( rhs_id, ast) ?;
768
+ cur_insts. push ( SVPrimitive :: new_const (
769
+ val,
770
+ lhs_name. clone ( ) ,
771
+ lhs_name + "_const_binary" ,
772
+ ) ) ;
729
773
}
730
774
}
731
775
NodeEvent :: Leave ( RefNode :: NetAssignment ( _net_assign) ) => ( ) ,
0 commit comments