diff --git a/pervognsen/bitwise/bitwise/bitwise058.hmml b/pervognsen/bitwise/bitwise/bitwise058.hmml index 43eb5ed..fd4612d 100644 --- a/pervognsen/bitwise/bitwise/bitwise058.hmml +++ b/pervognsen/bitwise/bitwise/bitwise058.hmml @@ -1,2 +1,74 @@ -[video member=pervognsen stream_platform=twitch project=bitwise title="Sequential Logic, Part 2" vod_platform=youtube id=kU9QIqdy5i0 annotator=] -[/video] \ No newline at end of file +[video member=pervognsen stream_platform=twitch project=bitwise title="Sequential Logic, Part 2" vod_platform=youtube id=kU9QIqdy5i0 annotator=Miblo] +[0:08][Recap and set the stage for the day continuing with :"sequential logic"][:speech] +[0:46][Review the off-by-one issue from yesterday, in which simulate_test() failed to update the module output values after a tick and before calling in to the tester][:"sequential logic" :research] +[2:18][On splitting the update logic into two parts][:"sequential logic" :research] +[3:39][Consult the emitted code of our entire circuit, on the update logic split between update() - computing outputs - and tick() - computing register values][:"sequential logic" :run] +[7:52][Note the fewer yields in example39_test()][:"sequential logic" :research] +[8:50][:Run simulate_test() successfully on example39_test][:emulation :"sequential logic"] +[9:03][Combinational pipelining][:"sequential logic" :speech] +[9:46][Introduce delay() to construct feed-forward register chains][:"sequential logic"] +[13:52][Define Example40 module as a delay][:"sequential logic"] +[15:18][Check the graph of Example40, the delay][:"debug visualisation" :"sequential logic" :run] +[15:54][Create simulation test for Example40][:emulation :"sequential logic"] +[16:46][:Run simulate_test() successfully on example40_test][:emulation :"sequential logic"] +[17:50][A few words on the utility of delay like an operator][:"sequential logic" :speech] +[21:49][Augmenting delay analysis to compute critical paths between internal registers][:profiling :"sequential logic" :speech] +[23:18][Change the DelayAnalyzer use nodes rather than node names][:profiling :"sequential logic"] +[29:45][:Run it to see our delay analysis][:profiling :"sequential logic"] +[30:49][Introduce combinational_multiplier() as a dumb multiplier][:"sequential logic"] +[34:19][:Run simulate_test() on the combinational_multiplier() successfully][:emulation :"sequential logic"] +[34:26][Introduce pipelined_multiplier() interspersing delay() in the combinational_multiplier(), also adding an "enable" control signal in Example42][:"sequential logic"] +[41:56][:Run it and hit runtime error "dictionary changed size during iteration"][:emulation :"sequential logic"] +[42:10][Enable linearize() to handle register discovery][:"code generation"] +[44:08][:Run it successfully][:emulation :"sequential logic"] +[44:13][Create a test of Example42 without pipelining][:"code generation" :emulation :"sequential logic"] +[45:00][:Run it, hit an AttributeError, and investigate the problem in register discovery][:"code generation" :emulation :"sequential logic"] +[50:45][Investigate the project in the combinational_multiplier()][:emulation :"sequential logic"] +[51:39][Pass through the __iter__() of SimulatorInstance while debugging][:"sequential logic"] +[52:06][Step through example42_test() inspecting the values][:emulation :"sequential logic" :run] +[53:28][Fix the "enable" control signal in Example42 to be a single bit][:"sequential logic"] +[53:43][:Run simulate_test() on example42_test to completion][:emulation :"sequential logic"] +[54:22][Change pipelined_multiplier() to use the current values of x and y before reassigning them][:"sequential logic"] +[56:00][:Run simulate_test() on example42_test, hit our test assertion and step in to pipelined_multiplier() to investigate][:emulation :"sequential logic"] +[58:05][Check out our generated code to see self.r8 being set incorrectly][:"sequential logic" :run] +[59:47][Change Example42 to set p and p_valid to their output() separately from the pipelined_multiplier() call][:"sequential logic"] +[1:00:06][:Run it to see the same p_valid value as before, and check the code][:"sequential logic" :run] +[1:01:51][Scrutinise linearize() to discover the issue][:"code generation" :research] +[1:02:42][Prevent name collision during register discovery in linearize()][:"code generation"] +[1:06:43][Realise that both update() and tick() need to use the same register names, and consider how to resolve our failure][:"code generation" :speech] +[1:07:28][Make linearize() use a shared dictionary for registers][:"code generation"] +[1:08:27][:Run it still unsuccessfully, with the same p_valid() value as before][:"code generation"] +[1:08:41][Make linearize() clone the counter as well][:"code generation"] +[1:09:01][:Run it successfully][:emulation :"code generation"] +[1:09:17][Try to clean up the update_instructions and tick_instructions split in linearize()][:"code generation"] +[1:10:55][:Run it and hit an AttributeError][:"code generation"] +[1:12:20][Revert linearize() to the working version][:"code generation"] +[1:12:56][:Run simulate_test() on the real example42_test unsuccessfully, and inspect the computed values][:emulation :"sequential logic"] +[1:16:56][Reformulate combinational_multiplier() as a parallel assignment][:"sequential logic"] +[1:17:51][:Run it to see that that works][:emulation :"sequential logic"] +[1:17:55][Change pipelined_multiplier() to use this new parallel formulation of combinational_multiplier()][:"sequential logic"] +[1:18:54][Enable delay() to handle tuples][:"sequential logic"] +[1:19:25][:Run it to see it still doesn't work][:"sequential logic"] +[1:19:28][Fix pipelined_multiplier() to iterate over all the bits][:"sequential logic"] +[1:19:33][:Run the pipelined multiplier successfully][:"sequential logic"] +[1:20:21][Introduce example42_test_producer() and example42_test_consumer() to give us two different agents to feed and consume from the multiplier][:"sequential logic"] +[1:22:04][Enable simulate_test() to handle multiple testers][:emulation] +[1:24:37][:Run it to ensure that the existing tests do run][:emulation] +[1:24:55][Write a simulation test of our multiplier producer and consumer running in parallel][:emulation :"sequential logic"] +[1:25:23][:Run simulate_test() on our multiplier producer and consumer, fail the test and investigate why][:emulation :"sequential logic"] +[1:28:43][Fix example42_test_consumer() to correctly yield][:"sequential logic"] +[1:29:17][:Run simulate_test() on our multiplier with parallel producer and consumer successfully][:emulation :"sequential logic"] +[1:29:25][@spriithy][New place?] +[1:29:45][Reflect on the utility of running more than one test co-routine at once][:emulation :"sequential logic" :speech] +[1:30:10][Further decouple the producer and consumer using a separate "expected" queue[ref + site="Python 3.7.0 documentation" + page="17.7. queue — A synchronized queue class" + url=https://docs.python.org/3/library/queue.html]][:"sequential logic"] +[1:33:23][:Run it to see that example42_test_consumer() never gets to run, and investigate why][:emulation :"sequential logic"] +[1:35:30][:Run it again to see that example42_test_consumer() now gets to run][:emulation :"sequential logic"] +[1:36:32][Revert the decoupling][:"sequential logic"] +[1:36:57][:Run it successfully][:"sequential logic"] +[1:37:17][Reflect on our pipelined system, impressing the need to keep thing in phase when mixing, and the utility of pipelining to improve the throughput of any combinational circuit][:"sequential logic" :speech] +[1:43:36][Pipelining a 1024-bit carry-propagate adder][:"sequential logic" :speech] +[1:51:37][That's it for the main stream][:speech] +[/video]