forked from libre-chip/fayalite
		
	change register names to end in _reg by convention
				
					
				
			This commit is contained in:
		
							parent
							
								
									ec77559e2b
								
							
						
					
					
						commit
						e05c368688
					
				
					 4 changed files with 87 additions and 69 deletions
				
			
		|  | @ -17,15 +17,15 @@ fn blinky(clock_frequency: u64) { | |||
|     let max_value = clock_frequency / 2 - 1; | ||||
|     let int_ty = UInt::range_inclusive(0..=max_value); | ||||
|     #[hdl] | ||||
|     let counter: UInt = reg_builder().clock_domain(cd).reset(0u8.cast_to(int_ty)); | ||||
|     let counter_reg: UInt = reg_builder().clock_domain(cd).reset(0u8.cast_to(int_ty)); | ||||
|     #[hdl] | ||||
|     let output_reg: Bool = reg_builder().clock_domain(cd).reset(false); | ||||
|     #[hdl] | ||||
|     if counter.cmp_eq(max_value) { | ||||
|         connect_any(counter, 0u8); | ||||
|     if counter_reg.cmp_eq(max_value) { | ||||
|         connect_any(counter_reg, 0u8); | ||||
|         connect(output_reg, !output_reg); | ||||
|     } else { | ||||
|         connect_any(counter, counter + 1_hdl_u1); | ||||
|         connect_any(counter_reg, counter_reg + 1_hdl_u1); | ||||
|     } | ||||
|     #[hdl] | ||||
|     let led: Bool = m.output(); | ||||
|  |  | |||
|  | @ -9,6 +9,9 @@ | |||
| //!
 | ||||
| //! Registers follow [connection semantics], which are unlike assignments in software, so you should read it.
 | ||||
| //!
 | ||||
| //! By convention, register names end in `_reg` -- this helps you tell which values are written
 | ||||
| //! immediately or on the next clock edge when connecting to them.
 | ||||
| //!
 | ||||
| //! ```
 | ||||
| //! # use fayalite::prelude::*;
 | ||||
| //! # #[hdl_module]
 | ||||
|  | @ -18,11 +21,11 @@ | |||
| //! #[hdl]
 | ||||
| //! let cd: ClockDomain = m.input();
 | ||||
| //! #[hdl]
 | ||||
| //! let my_register: UInt<8> = reg_builder().clock_domain(cd).reset(8_hdl_u8);
 | ||||
| //! let my_reg: UInt<8> = reg_builder().clock_domain(cd).reset(8_hdl_u8);
 | ||||
| //! #[hdl]
 | ||||
| //! if v {
 | ||||
| //!     // my_register is only changed when both `v` is set and `cd`'s clock edge occurs.
 | ||||
| //!     connect(my_register, 0x45_hdl_u8);
 | ||||
| //!     // my_reg is only changed when both `v` is set and `cd`'s clock edge occurs.
 | ||||
| //!     connect(my_reg, 0x45_hdl_u8);
 | ||||
| //! }
 | ||||
| //! # }
 | ||||
| //! ```
 | ||||
|  |  | |||
|  | @ -69,11 +69,11 @@ pub fn queue<T: Type>( | |||
|     let count: UInt = m.output(count_ty); | ||||
| 
 | ||||
|     #[hdl] | ||||
|     let inp_index = reg_builder().clock_domain(cd).reset(0.cast_to(index_ty)); | ||||
|     let inp_index_reg = reg_builder().clock_domain(cd).reset(0.cast_to(index_ty)); | ||||
|     #[hdl] | ||||
|     let out_index = reg_builder().clock_domain(cd).reset(0.cast_to(index_ty)); | ||||
|     let out_index_reg = reg_builder().clock_domain(cd).reset(0.cast_to(index_ty)); | ||||
|     #[hdl] | ||||
|     let maybe_full = reg_builder().clock_domain(cd).reset(false); | ||||
|     let maybe_full_reg = reg_builder().clock_domain(cd).reset(false); | ||||
| 
 | ||||
|     #[hdl] | ||||
|     let mut mem = memory(ty); | ||||
|  | @ -89,18 +89,18 @@ pub fn queue<T: Type>( | |||
|     connect(out_fire, ReadyValid::fire(out)); | ||||
|     #[hdl] | ||||
|     let indexes_equal: Bool = wire(); | ||||
|     connect(indexes_equal, inp_index.cmp_eq(out_index)); | ||||
|     connect(indexes_equal, inp_index_reg.cmp_eq(out_index_reg)); | ||||
|     #[hdl] | ||||
|     let empty: Bool = wire(); | ||||
|     connect(empty, indexes_equal & !maybe_full); | ||||
|     connect(empty, indexes_equal & !maybe_full_reg); | ||||
|     #[hdl] | ||||
|     let full: Bool = wire(); | ||||
|     connect(full, indexes_equal & maybe_full); | ||||
|     connect(full, indexes_equal & maybe_full_reg); | ||||
| 
 | ||||
|     connect(read_port.addr, out_index); | ||||
|     connect(read_port.addr, out_index_reg); | ||||
|     connect(read_port.en, true); | ||||
|     connect(read_port.clk, cd.clk); | ||||
|     connect(write_port.addr, inp_index); | ||||
|     connect(write_port.addr, inp_index_reg); | ||||
|     connect(write_port.en, inp_fire); | ||||
|     connect(write_port.clk, cd.clk); | ||||
|     connect(write_port.data, HdlOption::unwrap_or(inp.data, ty.uninit())); | ||||
|  | @ -127,33 +127,33 @@ pub fn queue<T: Type>( | |||
| 
 | ||||
|     #[hdl] | ||||
|     if inp_fire.cmp_ne(out_fire) { | ||||
|         connect(maybe_full, inp_fire); | ||||
|         connect(maybe_full_reg, inp_fire); | ||||
|     } | ||||
| 
 | ||||
|     #[hdl] | ||||
|     if inp_fire { | ||||
|         #[hdl] | ||||
|         if inp_index.cmp_eq(capacity.get() - 1) { | ||||
|             connect_any(inp_index, 0_hdl_u0); | ||||
|         if inp_index_reg.cmp_eq(capacity.get() - 1) { | ||||
|             connect_any(inp_index_reg, 0_hdl_u0); | ||||
|         } else { | ||||
|             connect_any(inp_index, inp_index + 1_hdl_u1); | ||||
|             connect_any(inp_index_reg, inp_index_reg + 1_hdl_u1); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[hdl] | ||||
|     if out_fire { | ||||
|         #[hdl] | ||||
|         if out_index.cmp_eq(capacity.get() - 1) { | ||||
|             connect_any(out_index, 0_hdl_u0); | ||||
|         if out_index_reg.cmp_eq(capacity.get() - 1) { | ||||
|             connect_any(out_index_reg, 0_hdl_u0); | ||||
|         } else { | ||||
|             connect_any(out_index, out_index + 1_hdl_u1); | ||||
|             connect_any(out_index_reg, out_index_reg + 1_hdl_u1); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[hdl] | ||||
|     if indexes_equal { | ||||
|         #[hdl] | ||||
|         if maybe_full { | ||||
|         if maybe_full_reg { | ||||
|             connect_any(count, capacity); | ||||
|         } else { | ||||
|             connect_any(count, 0_hdl_u0); | ||||
|  | @ -163,15 +163,18 @@ pub fn queue<T: Type>( | |||
|             debug_assert_eq!(count_ty.width(), index_ty.width() + 1); | ||||
|             #[hdl] | ||||
|             let count_lower = wire(index_ty); | ||||
|             connect(count_lower, (inp_index - out_index).cast_to(index_ty)); // wrap
 | ||||
|             connect( | ||||
|                 count_lower, | ||||
|                 (inp_index_reg - out_index_reg).cast_to(index_ty), | ||||
|             ); // wrap
 | ||||
|             connect(count, count_lower.cast_to(count_ty)); | ||||
|         } else { | ||||
|             debug_assert_eq!(count_ty.width(), index_ty.width()); | ||||
|             #[hdl] | ||||
|             if inp_index.cmp_lt(out_index) { | ||||
|                 connect(count, inp_index + capacity - out_index); | ||||
|             if inp_index_reg.cmp_lt(out_index_reg) { | ||||
|                 connect(count, inp_index_reg + capacity - out_index_reg); | ||||
|             } else { | ||||
|                 connect(count, inp_index - out_index); | ||||
|                 connect(count, inp_index_reg - out_index_reg); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | @ -249,89 +252,101 @@ mod tests { | |||
|             ); | ||||
| 
 | ||||
|             #[hdl] | ||||
|             let expected_count = reg_builder().clock_domain(cd).reset(0u32); | ||||
|             let expected_count_reg = reg_builder().clock_domain(cd).reset(0u32); | ||||
|             #[hdl] | ||||
|             let next_expected_count = wire(); | ||||
|             connect(next_expected_count, expected_count); | ||||
|             connect(expected_count, next_expected_count); | ||||
|             connect(next_expected_count, expected_count_reg); | ||||
|             connect(expected_count_reg, next_expected_count); | ||||
|             #[hdl] | ||||
|             if ReadyValid::fire(dut.inp) & !ReadyValid::fire(dut.out) { | ||||
|                 connect_any(next_expected_count, expected_count + 1u8); | ||||
|                 connect_any(next_expected_count, expected_count_reg + 1u8); | ||||
|             } else if !ReadyValid::fire(dut.inp) & ReadyValid::fire(dut.out) { | ||||
|                 connect_any(next_expected_count, expected_count - 1u8); | ||||
|                 connect_any(next_expected_count, expected_count_reg - 1u8); | ||||
|             } | ||||
|             hdl_assert(cd.clk, expected_count.cmp_eq(dut.count), ""); | ||||
|             hdl_assert(cd.clk, expected_count_reg.cmp_eq(dut.count), ""); | ||||
| 
 | ||||
|             #[hdl] | ||||
|             let prev_out_ready = reg_builder().clock_domain(cd).reset(!0_hdl_u3); | ||||
|             let prev_out_ready_reg = reg_builder().clock_domain(cd).reset(!0_hdl_u3); | ||||
|             connect_any( | ||||
|                 prev_out_ready, | ||||
|                 (prev_out_ready << 1) | out_ready.cast_to(UInt[1]), | ||||
|                 prev_out_ready_reg, | ||||
|                 (prev_out_ready_reg << 1) | out_ready.cast_to(UInt[1]), | ||||
|             ); | ||||
|             #[hdl] | ||||
|             let prev_inp_valid = reg_builder().clock_domain(cd).reset(!0_hdl_u3); | ||||
|             let prev_inp_valid_reg = reg_builder().clock_domain(cd).reset(!0_hdl_u3); | ||||
|             connect_any( | ||||
|                 prev_inp_valid, | ||||
|                 (prev_inp_valid << 1) | HdlOption::is_some(inp_data).cast_to(UInt[1]), | ||||
|                 prev_inp_valid_reg, | ||||
|                 (prev_inp_valid_reg << 1) | HdlOption::is_some(inp_data).cast_to(UInt[1]), | ||||
|             ); | ||||
|             hdl_assume( | ||||
|                 clk, | ||||
|                 (prev_out_ready_reg & prev_inp_valid_reg).cmp_ne(0u8), | ||||
|                 "", | ||||
|             ); | ||||
|             hdl_assume(clk, (prev_out_ready & prev_inp_valid).cmp_ne(0u8), ""); | ||||
| 
 | ||||
|             #[hdl] | ||||
|             let inp_index = reg_builder().clock_domain(cd).reset(index_ty.zero()); | ||||
|             let inp_index_reg = reg_builder().clock_domain(cd).reset(index_ty.zero()); | ||||
|             #[hdl] | ||||
|             let stored_inp_data = reg_builder().clock_domain(cd).reset(0u8); | ||||
|             let stored_inp_data_reg = reg_builder().clock_domain(cd).reset(0u8); | ||||
| 
 | ||||
|             #[hdl] | ||||
|             if let HdlSome(data) = ReadyValid::fire_data(dut.inp) { | ||||
|                 #[hdl] | ||||
|                 if inp_index.cmp_lt(index_max) { | ||||
|                     connect_any(inp_index, inp_index + 1u8); | ||||
|                 if inp_index_reg.cmp_lt(index_max) { | ||||
|                     connect_any(inp_index_reg, inp_index_reg + 1u8); | ||||
|                     #[hdl] | ||||
|                     if inp_index.cmp_eq(index_to_check) { | ||||
|                         connect(stored_inp_data, data); | ||||
|                     if inp_index_reg.cmp_eq(index_to_check) { | ||||
|                         connect(stored_inp_data_reg, data); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             #[hdl] | ||||
|             if inp_index.cmp_lt(index_to_check) { | ||||
|                 hdl_assert(clk, stored_inp_data.cmp_eq(0u8), ""); | ||||
|             if inp_index_reg.cmp_lt(index_to_check) { | ||||
|                 hdl_assert(clk, stored_inp_data_reg.cmp_eq(0u8), ""); | ||||
|             } | ||||
| 
 | ||||
|             #[hdl] | ||||
|             let out_index = reg_builder().clock_domain(cd).reset(index_ty.zero()); | ||||
|             let out_index_reg = reg_builder().clock_domain(cd).reset(index_ty.zero()); | ||||
|             #[hdl] | ||||
|             let stored_out_data = reg_builder().clock_domain(cd).reset(0u8); | ||||
|             let stored_out_data_reg = reg_builder().clock_domain(cd).reset(0u8); | ||||
| 
 | ||||
|             #[hdl] | ||||
|             if let HdlSome(data) = ReadyValid::fire_data(dut.out) { | ||||
|                 #[hdl] | ||||
|                 if out_index.cmp_lt(index_max) { | ||||
|                     connect_any(out_index, out_index + 1u8); | ||||
|                 if out_index_reg.cmp_lt(index_max) { | ||||
|                     connect_any(out_index_reg, out_index_reg + 1u8); | ||||
|                     #[hdl] | ||||
|                     if out_index.cmp_eq(index_to_check) { | ||||
|                         connect(stored_out_data, data); | ||||
|                     if out_index_reg.cmp_eq(index_to_check) { | ||||
|                         connect(stored_out_data_reg, data); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             #[hdl] | ||||
|             if out_index.cmp_lt(index_to_check) { | ||||
|                 hdl_assert(clk, stored_out_data.cmp_eq(0u8), ""); | ||||
|             if out_index_reg.cmp_lt(index_to_check) { | ||||
|                 hdl_assert(clk, stored_out_data_reg.cmp_eq(0u8), ""); | ||||
|             } | ||||
| 
 | ||||
|             hdl_assert(clk, inp_index.cmp_ge(out_index), ""); | ||||
|             hdl_assert(clk, inp_index_reg.cmp_ge(out_index_reg), ""); | ||||
| 
 | ||||
|             #[hdl] | ||||
|             if inp_index.cmp_lt(index_max) & out_index.cmp_lt(index_max) { | ||||
|                 hdl_assert(clk, expected_count.cmp_eq(inp_index - out_index), ""); | ||||
|             if inp_index_reg.cmp_lt(index_max) & out_index_reg.cmp_lt(index_max) { | ||||
|                 hdl_assert( | ||||
|                     clk, | ||||
|                     expected_count_reg.cmp_eq(inp_index_reg - out_index_reg), | ||||
|                     "", | ||||
|                 ); | ||||
|             } else { | ||||
|                 hdl_assert(clk, expected_count.cmp_ge(inp_index - out_index), ""); | ||||
|                 hdl_assert( | ||||
|                     clk, | ||||
|                     expected_count_reg.cmp_ge(inp_index_reg - out_index_reg), | ||||
|                     "", | ||||
|                 ); | ||||
|             } | ||||
| 
 | ||||
|             #[hdl] | ||||
|             if inp_index.cmp_gt(index_to_check) & out_index.cmp_gt(index_to_check) { | ||||
|                 hdl_assert(clk, stored_inp_data.cmp_eq(stored_out_data), ""); | ||||
|             if inp_index_reg.cmp_gt(index_to_check) & out_index_reg.cmp_gt(index_to_check) { | ||||
|                 hdl_assert(clk, stored_inp_data_reg.cmp_eq(stored_out_data_reg), ""); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -41,13 +41,13 @@ pub fn my_module(width: usize) { | |||
|     #[hdl] | ||||
|     let m2 = instance(module2()); | ||||
|     #[hdl] | ||||
|     let r: UInt<8> = reg_builder().clock_domain(clock_domain).reset(8_hdl_u8); | ||||
|     let r_reg: UInt<8> = reg_builder().clock_domain(clock_domain).reset(8_hdl_u8); | ||||
|     connect(m2.i, i); | ||||
|     connect(r, m2.o); | ||||
|     connect(r_reg, m2.o); | ||||
|     connect( | ||||
|         o, | ||||
|         #[hdl] | ||||
|         [r, r, b'\r'_hdl], | ||||
|         [r_reg, r_reg, b'\r'_hdl], | ||||
|     ); | ||||
|     connect(o[1], 30_hdl_u8); | ||||
|     connect(o2, i2); | ||||
|  | @ -109,12 +109,12 @@ circuit my_module: | |||
|         connect _bundle_literal_expr.`1`, SInt<5>(-0h3) | ||||
|         connect o3, _bundle_literal_expr @[module-XXXXXXXXXX.rs 12:1] | ||||
|         inst m2 of module2 @[module-XXXXXXXXXX.rs 13:1] | ||||
|         regreset r: UInt<8>, clock_domain.clk, clock_domain.rst, UInt<8>(0h8) @[module-XXXXXXXXXX.rs 14:1] | ||||
|         regreset r_reg: UInt<8>, clock_domain.clk, clock_domain.rst, UInt<8>(0h8) @[module-XXXXXXXXXX.rs 14:1] | ||||
|         connect m2.i, i @[module-XXXXXXXXXX.rs 15:1] | ||||
|         connect r, m2.o @[module-XXXXXXXXXX.rs 16:1] | ||||
|         connect r_reg, m2.o @[module-XXXXXXXXXX.rs 16:1] | ||||
|         wire _array_literal_expr: UInt<8>[3] | ||||
|         connect _array_literal_expr[0], r | ||||
|         connect _array_literal_expr[1], r | ||||
|         connect _array_literal_expr[0], r_reg | ||||
|         connect _array_literal_expr[1], r_reg | ||||
|         connect _array_literal_expr[2], UInt<8>(0hD) | ||||
|         connect o, _array_literal_expr @[module-XXXXXXXXXX.rs 17:1] | ||||
|         connect o[1], UInt<8>(0h1E) @[module-XXXXXXXXXX.rs 18:1] | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue