[video member=pervognsen stream_platform=twitch project=bitwise title="Logic Design, Part 6" vod_platform=youtube id=vbjV_1EBbTg annotator=Miblo]
[0:06][Recap and set the stage for the day revisiting ALU before going on to shifters][:"logic design" :speech]
[1:18][Review our adders][:"logic design" :research]
[2:37][Review off-stream introduction of Kogge Stone scan][:"logic design" :research]
[4:23][Review off-stream introduction of analyze_delay()][:"logic design" :profiling :research]
[8:04][Instantiate 32-bit and 4-bit bit adders to compare their delay with the 64-bit ones][:"logic design" :performance :run]
[9:57][Shifters][:"logic design" :speech]
[12:23][Set up to implement dynamic shift in terms of static shift][:"logic design" :speech]
[13:42][Introduce left_shifter()][:"logic design"]
[16:50][Define Example16 as a left shifter module][:"logic design"]
[18:47][Check out our left shifter graph][:"debug visualisation" :"logic design" :run]
[19:21][Instantiate a 16-bit shifter and check out its graph][:"debug visualisation" :"logic design" :run]
[20:43][Define Mux4 module][:"logic design"]
[22:43][Introduce left_shifter_radix2() and left_shifter_radix4() based on our original left_shifter()][:"logic design"]
[25:25][Define Example17 using left_shifter_radix4()][:"logic design"]
[25:48][Check out the graph to find that left_shifter_radix4() does not work][:"debug visualisation" :"logic design" :run]
[27:18][Redefine Example17 using just mux4()][:"logic design"]
[27:48][Check out the mux4 graph to see that that works][:"debug visualisation" :"logic design" :run]
[28:00][Fix left_shifter_radix4() to loop over the correct range][:"logic design"]
[28:43][Check out the left_shifter_radix4() graph][:"debug visualisation" :"logic design" :run]
[29:38][Instantiate a 32-bit shifter, and enable left_shifter_radix4() to handle odd-numbered shift bits][:"logic design"]
[31:01][Check out the graph to see that it is not as expected][:"debug visualisation" :"logic design" :run]
[31:22][Change left_shifter_radix4() to handle odd-numbered shift bits inside its loop][:"logic design"]
[32:00][Check out the graph of our 32-bit left shifter][:"debug visualisation" :"logic design" :run]
[32:32][Reflect on our single logarithmic shifter, with a brief mention of linear shifters][:"logic design" :speech]
[33:44][Right-shifting, both logical and arithmetic][:"logic design" :speech]
[35:27][Q&A][:speech]
[35:43][@rygorous][The typical array / linear shifter layout does not have N layers. Instead you basically have N layers "deep" of tristate drivers on one long wire, and only one of them is active, the rest is Z. So that's not N layers deep of logic, basically one layer][:"logic design"]
[36:16][Recommend Mean and Conway's 'Introduction to VLSI systems'[ref
    author="Carver Mead and Lynn Conway"
    title="Introduction to VLSI systems"
    url=https://www.researchgate.net/publication/234388249_Introduction_to_VLSI_systems]][:"logic design" :research]
[37:37][Introduce rotator_radix2][:"logic design"]
[39:41][Define Example18 as a left-rotator][:"logic design"]
[40:09][Instantiate a 16-bit left-rotator and check out its graph][:"debug visualisation" :"logic design" :run]
[41:10][Rename rotator_radix2() to left_rotator_radix2() and introduce right_rotator_radix2() using it][:"logic design"]
[44:15][Introduce __neg__() – unary minus operator – in rattle][:language]
[45:36][Check out our right-rotator graph][:"debug visualisation" :"logic design" :run]
[46:42][Introduce the notion of pre-rotation in right_rotator_radix2()][:"logic design"]
[48:25][Check out our pre-rotated right rotator graph][:"debug visualisation" :"logic design" :run]
[48:32][Test our shifters in the simulator][:emulation :"logic design" :run]
[50:38][Test our rotators in the simulator, introducing rotl() and rotr()][:emulation :"logic design" :run]
[53:37][All the tests passed at the first try][:"logic design" :speech]
[54:43][@rygorous][@pervognsen Probably want to mask both sides for rotl() / rotr() so it works with signed values][:"logic design"]
[54:47][Enable rotl() and rotr() to work with signed values][:"logic design"]
[55:02][Set up to create our first combined design: Barrel shifter][:"logic design" :speech]
[56:32][Introduce barrel_left_shifter()][:"logic design"]
[59:54][Define Example20 as a left barrel shifter][:"logic design"]
[1:00:37][Simulate the left barrel shifter and fail the verification test][:emulation :"logic design" :run]
[1:01:22][Fix missing comma in binary_ops][:language]
[1:01:48][Test the correct module in Example20, and simulate it to find that it passes][:emulation :"logic design" :run]
[1:02:25][@miotatsu][Wow, that implicit string concatenation there is nasty][:language]
[1:02:33][Introduce barrel_right_shifter()][:"logic design"]
[1:05:15][Explain inference of literal types][:language :speech]
[1:06:04][Define Example21 as a right barrel shifter][:"logic design"]
[1:06:32][Simulate the right barrel shifter, fail the test and investigate why][:emulation :"logic design" :run]
[1:14:49][@nothings2][How is it that the outer assertion has access to 'mask'? Is this a weird pythonism?][:language]
[1:15:04][Print the mask of barrel_right_shifter()][:"logic design"]
[1:16:13][:Run it and check out the mask][:emulation :"logic design"]
[1:16:56][Fix the mask computation in barrel_right_shifter()][:"logic design"]
[1:17:11][Simulate the right barrel shifter and pass the test][:emulation :"logic design" :run]
[1:17:19][Remove the mask printout][:"logic design"]
[1:18:11][Simulate it, pass the test and reflect on the right barrel shifter][:emulation :"logic design" :run]
[1:19:06][Introduce barrel_arithmetic_right_shifter()][:"logic design"]
[1:22:02][@rygorous][@pervognsen Don't you really need a mux? Since you need to either clear or set the upper bits, neither AND nor OR by itself can work][:"logic design"]
[1:22:32][Enable barrel_arithmetic_right_shifter() to mux between clearing and setting the upper bits][:"logic design"]
[1:24:54][Simulate the barrel_arithmetic_right_shifter() on a signed input to find that it works][:emulation :"logic design" :run]
[1:25:04][Introduce barrel_shifter() as our first combined design][:"logic design"]
[1:35:34][Define Example23 as a unified barrel shifter][:"logic design"]
[1:37:26][Simulate our unified barrel shifter on left- and right-rotations and left-shift, to find that they all work][:emulation :"logic design" :programming :run]
[1:40:06][Simulate right-shift to find that it doesn't work, and investigate why][:emulation :"logic design" :run]
[1:42:00][Print the mask of barrel_shifter()][:"logic design"]
[1:42:55][@rygorous][@pervognsen But now you're passing in \~n (from the first mux) when dir=1][:"logic design"]
[1:43:05][Enable barrel_shifter() to correctly perform right-shift][:"logic design"]
[1:43:44][Simulate the barrel shifter on right-shift, and pass the test][:emulation :"logic design" :run]
[1:44:05][Simulate the barrel shifter on arithmetic shift, and pass][:emulation :"logic design" :run]
[1:44:40][@rygorous][@pervognsen Basically, for the rotate case, just force mask to all-1s and delete the output mux][:"logic design"]
[1:44:48][Change barrel_shifter() to force the mask to all 1s and delete the output mux in the rotate case][:"logic design"]
[1:45:46][Simulate it to find that it works][:emulation :"logic design" :run]
[1:46:09][Introduce left_rotator_radix4()][:"logic design"]
[1:50:03][Check out the left_rotator_radix4 graph to see that it looks reasonable][:"debug visualisation" :"logic design" :run]
[1:50:33][Instantiate an 8-bit rotator and check out its graph][:"debug visualisation" :"logic design" :run]
[1:52:10][Test barrel_shifter() using both left_rotator_radix2() and left_rotator_radix4() to see that it works][:emulation :"logic design" :programming :run]
[1:53:03][Check out the graph of our unified barrel shifter][:"debug visualisation" :"logic design" :run]
[1:53:20][@rygorous][@pervognsen Why m1, m2, m3 and not m,2*m,3*m?]
[1:53:26][Rewrite left_rotator_radix4() as per @rygorous's suggestion]
[1:53:55][Consult the graph of our unified barrel shifter][:"debug visualisation" :"logic design" :run]
[1:54:34][Instantiate a 16-bit barrel shifter and check out its graph, noting the importance of the mask being off the critical path][:"debug visualisation" :"logic design" :run]
[1:57:54][@rygorous][@pervognsen Other things: 1. Bit-reversal shifters! 2. Funnel shifters!][:"logic design"]
[1:58:02][Funnel shifters][:"logic design" :speech]
[2:02:30][Introduce double_width_shifter() as a funnel shifter][:"logic design"]
[2:06:15][Define Example24 as a funnel shifter][:"logic design"]
[2:07:09][Instantiate a 16-bit funnel shifter and check out its graph, to see that it is off-by-one][:"debug visualisation" :"logic design" :run]
[2:10:21][Shrink the x input of our funnel shifter by one bit][:"logic design"]
[2:10:38][Check out our funnel shifter graph to see that it looks good][:"debug visualisation" :"logic design" :run]
[2:10:50][Rename double_width_shifter() to funnel_shifter()][:"logic design"]
[2:11:17][Create a test of our funnel shifter][:emulation :"logic design"]
[2:13:48][Simulate a 16-bit and 4-bit funnel shifter to see that it passes][:emulation :"logic design" :run]
[2:14:17][Introduce funnel_right_shifter()][:"logic design"]
[2:16:33][Simulate a funnel right shifter to see that it passes][:emulation :"logic design" :run]
[2:16:59][Introduce funnel_left_shifter()][:"logic design"]
[2:18:19][@rygorous][@pervognsen You need to be careful with the opposite-direction shifts later (so if you do a right shift funnel, look at the left shift)][:"logic design"]
[2:18:33][Simulate a funnel left shifter to see that it fails][:emulation :"logic design" :run]
[2:19:40][Fix funnel_left_shifter()][:"logic design"]
[2:20:06][Introduce funnel_arithmetic_right_shifter()][:"logic design"]
[2:21:44][Simulate the funnel arithmetic right shifter, fail the test and investigate why][:emulation :"logic design" :run]
[2:25:31][Make funnel_arithmetic_right_shifter() use rep()][:"logic design"]
[2:25:44][Simulate the funnel arithmetic right shifter and pass the test][:emulation :"logic design" :run]
[2:26:33][Introduce funnel_right_rotator()][:"logic design"]
[2:27:48][Simulate the funnel right rotator successfully][:emulation :"logic design" :run]
[2:27:54][Introduce funnel_left_rotator()][:"logic design"]
[2:28:35][Simulate the funnel left rotator and fail the test][:emulation :"logic design" :run]
[2:28:54][@rygorous][@pervognsen I think x\[1:\], but yeah][:"logic design"]
[2:29:03][Fix funnel_left_rotator() to slice off the correct bit][:"logic design"]
[2:29:09][Simulate the funnel left rotator successfully][:emulation :"logic design" :run]
[2:29:17][Introduce funnel_shifter_unit() as a combined design][:"logic design"]
[2:31:15][@rygorous][@pervognsen You probably want to cut the slices into three pieces: hi 31, middle, lo 31. That way each of the pieces needs fewer options (instead of having a big full-width mux)][:"logic design"]
[2:31:27][Q&A][:speech]
[2:32:09][@tw0st3p][Question for an after hours stream: Have you heard of Julia :language?]
[2:32:50][Try to time the :performance of our barrel shifter, modifying get_operator_delay() to handle the necessary operators][:profiling]
[2:34:38][Check out the delay of our barrel shifter][:"logic design" :performance :run]
[2:35:38][Call it a day][:speech]
[/video]
