@@ -3,6 +3,178 @@ use fil_ir::{self as ir, AddCtx, MutCtx};
33use fil_utils:: GPosIdx ;
44use std:: path:: PathBuf ;
55
6+ // Delay shift register for interface-less components
7+ pub fn create_delay_shift_register ( ctx : & mut ir:: Context ) -> ir:: CompIdx {
8+ let mut sv_file = <PathBuf as From < _ > >:: from ( file ! ( ) ) ;
9+ sv_file. pop ( ) ;
10+ sv_file. push ( "register.sv" ) ;
11+
12+ log:: debug!(
13+ "Adding external scheduling register from {}" ,
14+ sv_file. display( )
15+ ) ;
16+
17+ // Next, build the external component
18+ let mut comp =
19+ ir:: Component :: new ( ir:: CompType :: External , Default :: default ( ) ) ;
20+
21+ let mut src_info =
22+ ir:: InterfaceSrc :: new ( "__SchedulingDelayShift" . into ( ) , None ) ;
23+
24+ // Set up parameters to the component
25+
26+ let width = comp. add ( ir:: Info :: param ( "WIDTH" . into ( ) , GPosIdx :: UNKNOWN ) ) ;
27+ let width = comp. add ( ir:: Param :: new ( ir:: ParamOwner :: Sig , width) ) ;
28+
29+ let delay = comp. add ( ir:: Info :: param ( "DELAY" . into ( ) , GPosIdx :: UNKNOWN ) ) ;
30+ let delay = comp. add ( ir:: Param :: new ( ir:: ParamOwner :: Sig , delay) ) ;
31+
32+ let live = comp. add ( ir:: Info :: param ( "LIVE" . into ( ) , GPosIdx :: UNKNOWN ) ) ;
33+ let live = comp. add ( ir:: Param :: new ( ir:: ParamOwner :: Sig , live) ) ;
34+
35+ // Add the parameters to the component
36+ src_info. params . push ( width, "WIDTH" . into ( ) ) ;
37+ src_info. params . push ( delay, "DELAY" . into ( ) ) ;
38+ src_info. params . push ( live, "LIVE" . into ( ) ) ;
39+
40+ // Intern the proposition that LIVE == 1 (as this is interfaceless)
41+ let live_expr = comp. add ( ir:: Expr :: Param ( live) ) ;
42+ let live_prop = ir:: Prop :: Cmp ( ir:: CmpOp :: eq (
43+ live_expr,
44+ comp. add ( ir:: Expr :: Concrete ( 1 ) ) ,
45+ ) ) ;
46+ let live_prop = comp. add ( live_prop) ;
47+ let live_info = comp. add ( ir:: Info :: assert ( ir:: info:: Reason :: misc (
48+ "Signature assumption" ,
49+ GPosIdx :: UNKNOWN ,
50+ ) ) ) ;
51+
52+ comp. add_param_assert ( [ ( live_prop, GPosIdx :: UNKNOWN ) ] ) ;
53+ comp. param_args = Box :: new ( [ width, delay, live] ) ;
54+
55+ let live_assumption = comp. assume ( live_prop, live_info) ;
56+ comp. cmds . extend ( live_assumption) ;
57+
58+ let width = comp. add ( ir:: Expr :: Param ( width) ) ;
59+ let delay = comp. add ( ir:: Expr :: Param ( delay) ) ;
60+
61+ // Concrete expressions
62+ let zero = comp. add ( ir:: Expr :: Concrete ( 0 ) ) ;
63+ let one = comp. add ( ir:: Expr :: Concrete ( 1 ) ) ;
64+
65+ let delay_1 = comp. add ( ir:: Expr :: Bin {
66+ op : ast:: Op :: Add ,
67+ lhs : delay,
68+ rhs : one,
69+ } ) ;
70+
71+ // Set up the event of the component
72+ let event = comp. add ( ir:: Info :: event (
73+ "G" . into ( ) ,
74+ GPosIdx :: UNKNOWN ,
75+ GPosIdx :: UNKNOWN ,
76+ None ,
77+ ) ) ;
78+ let event = comp. add ( ir:: Event {
79+ delay : ir:: TimeSub :: Unit ( one) ,
80+ info : event,
81+ has_interface : false ,
82+ } ) ;
83+ src_info. events . push ( event, "G" . into ( ) ) ;
84+ comp. event_args = Box :: new ( [ event] ) ;
85+
86+ // Set up ports to the component
87+
88+ // clk and reset ports are unannotated
89+ comp. unannotated_ports =
90+ Box :: new ( vec ! [ ( "clk" . into( ) , 1 ) , ( "reset" . into( ) , 1 ) ] ) ;
91+
92+ // input port
93+ let input = ir:: Port {
94+ owner : ir:: PortOwner :: Sig {
95+ dir : ir:: Direction :: Out ,
96+ } ,
97+ width,
98+ live : ir:: Liveness {
99+ idxs : vec ! [ ] ,
100+ lens : vec ! [ comp. add( ir:: Expr :: Concrete ( 1 ) ) ] ,
101+ range : ir:: Range {
102+ start : comp. add ( ir:: Time {
103+ event,
104+ offset : zero,
105+ } ) ,
106+ end : comp. add ( ir:: Time { event, offset : one } ) ,
107+ } ,
108+ } ,
109+ info : comp. add ( ir:: Info :: port (
110+ "in" . into ( ) ,
111+ GPosIdx :: UNKNOWN ,
112+ GPosIdx :: UNKNOWN ,
113+ GPosIdx :: UNKNOWN ,
114+ ) ) ,
115+ } ;
116+ let input = comp. add ( input) ;
117+ let input_param = ir:: Param {
118+ owner : ir:: ParamOwner :: bundle ( input) ,
119+ info : comp. add ( ir:: Info :: param ( "_" . into ( ) , GPosIdx :: UNKNOWN ) ) ,
120+ } ;
121+ let input_param = comp. add ( input_param) ;
122+
123+ comp. get_mut ( input) . live . idxs . push ( input_param) ;
124+ src_info. ports . push ( input, "in" . into ( ) ) ;
125+
126+ // output port
127+ let output = ir:: Port {
128+ owner : ir:: PortOwner :: Sig {
129+ dir : ir:: Direction :: In ,
130+ } ,
131+ width,
132+ live : ir:: Liveness {
133+ idxs : vec ! [ ] ,
134+ lens : vec ! [ comp. add( ir:: Expr :: Concrete ( 1 ) ) ] ,
135+ range : ir:: Range {
136+ start : comp. add ( ir:: Time {
137+ event,
138+ offset : delay,
139+ } ) ,
140+ end : comp. add ( ir:: Time {
141+ event,
142+ offset : delay_1,
143+ } ) ,
144+ } ,
145+ } ,
146+ info : comp. add ( ir:: Info :: port (
147+ "out" . into ( ) ,
148+ GPosIdx :: UNKNOWN ,
149+ GPosIdx :: UNKNOWN ,
150+ GPosIdx :: UNKNOWN ,
151+ ) ) ,
152+ } ;
153+ let output = comp. add ( output) ;
154+
155+ let output_param = ir:: Param {
156+ owner : ir:: ParamOwner :: bundle ( output) ,
157+ info : comp. add ( ir:: Info :: param ( "_" . into ( ) , GPosIdx :: UNKNOWN ) ) ,
158+ } ;
159+ let output_param = comp. add ( output_param) ;
160+
161+ comp. get_mut ( output) . live . idxs . push ( output_param) ;
162+ src_info. ports . push ( output, "out" . into ( ) ) ;
163+
164+ comp. src_info = Some ( src_info) ;
165+ comp. port_attrs = ir:: DenseIndexInfo :: with_default ( comp. ports ( ) . len ( ) ) ;
166+
167+ // Add the component to the context
168+
169+ let compidx = ctx. add ( comp) ;
170+
171+ // Add the component to the external list
172+ let filename = sv_file. to_str ( ) . unwrap ( ) . to_string ( ) ;
173+ ctx. externals . entry ( filename) . or_default ( ) . push ( compidx) ;
174+
175+ compidx
176+ }
177+
6178pub fn create_delay_register ( ctx : & mut ir:: Context ) -> ir:: CompIdx {
7179 let mut sv_file = <PathBuf as From < _ > >:: from ( file ! ( ) ) ;
8180 sv_file. pop ( ) ;
0 commit comments