diff --git a/tutorials/soc/lesson12/image.hex b/tutorials/soc/lesson12/image.hex new file mode 100644 index 0000000..63ed88f --- /dev/null +++ b/tutorials/soc/lesson12/image.hex @@ -0,0 +1,502 @@ +:020000040000FA +:200000000000000000000000000000000000000000000000000000000000000000000001DF +:2000200000002000000024010000200000000001000024252424240524040400000024252B +:200040002400000000002425200000000000000000000000000000010000242548496C4D7F +:2000600048040400000024252424282528252825242424042404242524002400040424243F +:200080002400240424242829282424000000000004284828040024294C4D28040000000158 +:2000A00000000000000000000000000000000000000000000000000000000000002400001C +:2000C000002400240024002400240000002000000024042824280024002400040000002440 +:2000E000002400240024012400200020000000000000000000240000002400242448284CE3 +:2001000024240004002400240424002404240424002404240024002424240024042404245F +:2001200004240024042824482428002400200004044C284C04240428284C28280024000047 +:2001400000000000000000000000000000000000000000000000000000000000000100009E +:20016000000000000000240024000000200000000000242424252400000000000000000062 +:200180002400000024012400000000000000000000000000242524000000040024242424F1 +:2001A0002404040000000400040000000400040004052405040004042424242424252404C4 +:2001C0002404242424252424242424000000000428494C4D4C2928294C4D4C284849280018 +:2001E00000000024000000000000000000000000000000240000002400000024000000244B +:200200000000002400240024002400242044242400242044242424240024002400000024FA +:200220000024002400240024000000240000000000000024002400240024002400242428E6 +:200240000024002400240024000000040004002400240024002400240428042804280428A2 +:2002600004240428042424240024002400200024284C4C704D4C484C484C494C496D492485 +:2002800000000000000000000000000000000000000000000000000000000001000000005D +:2002A0000000000100002425240024252424444544242424242424252000200100002021F3 +:2002C000242524252400242100000000000000000000000124242400000024012400242425 +:2002E0000400000100002401000000000000000000000001000004252804282428042829B5 +:2003000024042425240424250000200100000425284D5051704D4C2948284C72957271497A +:20032000000000000000000000000000000000000000000000000000000000040024000095 +:2003400000000000002400240024002420242048244824242448242400240020002400246D +:200360000024002400240024002000000000000000000024002400240024002400240024D1 +:20038000002400000024002400240024000400000000000000240428282804280428082C79 +:2003A000042400240024002400240000002400240448284C4C7028482428259196B69291E0 +:2003C00000000000000000000000000000000000000000000000000000000000000000001D +:2003E00000000000000000002400200020002000242424002425242020000000240000003C +:200400002425240000002000000000000000000000000000242524000000000004002400BA +:20042000000000000000000000010400000000000000000000002429282928282828282829 +:2004400028040400040424042400000000010000040428294C4D4C28240424496D92957216 +:20046000000000240000002400000024000000240024002400000000000000240000000080 +:20048000000000240004002400240024002000240024002400240024002400240000002488 +:2004A00000240024002000240000002000000024000000240024002400240024002424244C +:2004C000002400240000002400240024002400200020002400040428082C282C082C282CA0 +:2004E0002424002400040024000000240020000400040428284C284804240024256D6D6D54 +:200500000000000000000001000000000000000000002401000000000000000100000001B3 +:2005200000000001000000010000200124000001000000000000240000002401200000000A +:200540000000242520002000000000000000000100000000240024010000240024254825EE +:2005600024002000000000000000242524252421000000000000042528282C2C2C282C29E6 +:200580002804240000000001000000000000000104052829282828242400040124496D29E7 +:2005A00000000000002400240024000000000000002400240000000000240024002400001B +:2005C00000000020002400200020002400240024002000240024002400240024002400240F +:2005E000002400240024002000240020002000000024002000240020002400242448252486 +:20060000002400240024000400242149254825240020002000040028284C284C282C282C2A +:2006200028280024002400000004002400000024284C282C0828242800240004046D494868 +:2006400000000000000000000000000000000000000000000000000000000000000000009A +:20066000000000000000000000000000202124002000200020212421240020002020242087 +:20068000200020002001200024000000000000000000000020002000202024244424240061 +:2006A00024000000200000000001244548494825240000000400040428282C2C2C2C2C280A +:2006C000282400000000000000000000000004254C292C2828282804240000002429482582 +:2006E0000000002400240024000000000000002400000024000000240000002400000000FE +:200700000000002400240024002000240024002400202044456D4948202424440024202406 +:200720000020002400240024002400240020002400200020002000240044244825440024E0 +:200740000024002400240024002425494549454820240024002404280428284C284C282C3C +:2007600024240024000000040000000000000448284C282C282804280024002400240424E5 +:20078000000000010000240100000000000000000000000000000000000000010000000032 +:2007A0000000000000002400000020212020242524458D8DB1B6B18D6C6D916D442544257A +:2007C000202024252020242520002000000020012000202120002020242544454424242067 +:2007E000202020212021242120002445484948252424242524242804042428294C4C4C28E1 +:20080000240400000000000000000000000024294C2C2C2C2C2824040400240500000000EA +:20082000000000240024002400240000000000000000000000000000002400000000000004 +:20084000000000000024002400200024448C698D8DD5D6FADAFDDAFAD6FEDADA91B18D8D85 +:20086000698D696924440024002400200024002000240024002420484468444844440024E4 +:2008800000200024002400242044214445482024202404282428042804280428284C28282E +:2008A00004240000002000000000000000000028284C284C28280404002400240004000438 +:2008C000000000000001000000000000000000000000000000000000000000000000000017 +:2008E000000000000001202020214469B1DAF9FAF9FAD9D6D9DAF9FAFDFEFDFEFEFFFEFA18 +:20090000FAD6D5B28C494445484524202420242424254445686D91B6B5B6B5B2B58D44453A +:200920004825242024202445686944254425240024202424282928242404240428252404A4 +:2009400024040000000000000000000000000424284D4C49280404002405240000000400BC +:2009600000000024002400240000002400000000000000000000002400000024000000009F +:200980000000002000202044448D91F9FAFEDAF9D5D5D5FDDAFDFAFDDAFDFAFDDAFEFEFEA1 +:2009A000FAFEFAFED6DAB6FAB6B56D68244849918DB1B2FADAFEDAFEFEFEFEFEDADAB1D991 +:2009C000D6B169684448488C6D8D44242044202400240028244828280424002400240024B9 +:2009E00000240024000000040000002400240024044828480004000400240024000400240B +:200A00000000000000000400000000000000000000000000000000010000000000000000D1 +:200A2000000020252420448DD5FAFDFAF9D6D5D5D5D9F9FAF9FAFDFAF9FAFDDAD9DAFDFE1A +:200A4000F9FAF9FAF9FAFEFFFEFFFEDBD9DAFEFFFEFFFEFFFEFEFDDAFDFEFEFEFEFAFEFE82 +:200A6000FDDAF9FAF9DAF9D6D5B16824242524212000242528294829240404000000000112 +:200A8000040424000000000100000000000024050400240000000400000024040424282537 +:200AA0000000000000240000000000000000000000040000000000000004000000200000EA +:200AC0000020448D8DB1B1F5D5F9FAF9D5F9D5F9D5F9D9FDF9FDFAFDF9F9D5F9D5F9D5F9F7 +:200AE000D9FDDAFDFAFEDEFEDEFEFEFEFAFEFEFEFEFEFEFEFAFEDAFDD9FDDAFEFAFDDAFD66 +:200B0000DAFDDAFEFEFEDAFEFAD96D440024002400200024244825482424000000000024FD +:200B2000002400000000000000000004002404240004002400240024000400240448242415 +:200B400000000000000000000000000000000000000000000000000000000000000120254F +:200B60006465ACD2F5D2F5F6F9FAF9D5F5F5F5D5F5FAF9FAFDFAF9FAF9F9F8F5F9D5D9D9DC +:200B8000FDFAFDFEFDFEFDFEFDFEFDFEFEFEFEFEFDFEFDDEFDFEFDFEFDFEFDFEFDFEFDFACB +:200BA000FDFEFDFEFDFEFDFAFDDAB58D91B2918D480020254825242424000000000100016B +:200BC00024002000000000000000000000002425240000002405240000000404242524257D +:200BE000000000000000000000000000000000240000000000000004000000240044448998 +:200C0000A9CDCDF1D1F5D5F9D5F5D5F5D1F5D5F9D5F9F9FDD9F9D9F9D5F9D9F9D9F9D5FD38 +:200C2000DAFDD9FDDAFEFEFEDAFEFAFDDAFEFEFEDAFDDAFDDAFDDAFDDAFEFEFDDAFDDEFDAF +:200C4000DAFDDAFDDEFEFAFEDAF9DAF9DAFEDAFE91682424002424240024000000200024A7 +:200C600000240024000000000000000400240048252400240024002400000024042404288F +:200C8000000000000000000000000000000000000000000000000000000020004065A8AD3A +:200CA000ECCDECEDF0F1F5F6F5F1F0F1F4F5F5F5F9F5F9F9F8D5F9D5D4D5F9FAF9F9F9FA40 +:200CC000FDFAFDFAFDFAFDFEFDDEFDFAF9DAFDFEFDDEFDFEFDFEFDFEFDFEFDFEFDDAFDFE00 +:200CE000FDDEFDFEFDFEFDFEF9DAF9FAF9FAFDFEF9B66D25000024252400000000002001A5 +:200D000000002400000000000000000000000425242524042404240000000425242424250F +:200D20000000000000000024000000000000000000000000000000000024204460A8C9ED49 +:200D4000E9E8C9EDCDF0D1F1CDF1CDF1D1F5F5F5D5F5D5F9F5F9D5F5D5F9D5F9D5FDF9FDAD +:200D6000D9FDDAFDFAFEFAFEFAFDDAFDD9FDDAFEFAFDDAFEFEFDFAFDFAFDDAFDDAFDDAFD1D +:200D8000DAFDDAFDD9FDFAFDD9FDDAF9D5F9DAFDFAFE8D4400242448242400200020002089 +:200DA00000240024002400240024000000040024002404240424002400240024042804281F +:200DC00000000000000000000000000000000000000000000000000000006465C8C9E8E9E8 +:200DE000E8E5E8E9ECEDECCDECEDF0EDF0F1F4F5F4D5F5F5F5F5F4F5F4F5F8F5F9F9F9F903 +:200E0000F9FAFDFAFDFAFDFEFDFAF9FAFDFEFDFEFDFEFDFAFDFEFDFAF9FAF9FAFDFEFDFE56 +:200E2000FDFAF9DAFDFAFDFAF9FAF9F9F9D5F9D5D5B16C242024242524242000000000006E +:200E400000002400000000002400000000000000000024042404040000002404242524253C +:200E6000000000000000000000000000000000000000002000000024002464ADC9E9E5E87A +:200E8000E5E8E9E8C9ECC9ECC9EDCDF1CDF1D1F5D1F5F1F5D1F5D1F5D1F5F5F9D5F9D5F9CA +:200EA000D5F9F9FDDAFDFAFDDAFDF9FDDAFDFEFDFAFDDAFDDAFDF9FDD5F9D5FDD9FDFAFDF9 +:200EC000DAFDF9FDD9FDF9FDD9F9D5F9D5F5D5D5B1D5918D49482448242400240020002018 +:200EE000002400240000002400240024000000000000002400240024002404240024042836 +:200F00000000000000000000000000000000000000000000000000002020A4A9E8E5E4E5AE +:200F2000E4C5E8E5E8E9ECEDECEDF0F1F0D1F5F6F0D1F1F1F0D1F0F1F0F1F4F5F4F5F5F549 +:200F4000F9F9F9FAF9D9F9FAFDFAF9FAF9FAFDFEFDFAFDFAF9DAF9D9F4F5F9FAF9FAFDFAB6 +:200F6000FDFAFDFAF9D5F9FAF9F9F9F6F5D5F9F6F9D6FADAB59291492420240000000000FC +:200F80000000240000000001040024000000000100000000240024000404282524042425F5 +:200FA000002400240000000000000000000000000000000000000020004485C9E5E8C5E4C1 +:200FC000C4E4C0E4C4E8C9ECCDF0CDF1D1F5F1F5D1F0CDF1CDF0CDF1CDF0CDF1D1F5D5F934 +:200FE000F5F9D5F5D5F9D5F9F9FDD9F9D9F9D9FDD9FDD9FDD9FDD5F9D5F9F5F9D9FDDAFD74 +:20100000F9FDF9F9D5F9D5F9D5F9F9F9D5F9D5F9DAFDFAFEDAFEB69148480024002000200E +:201020000024002400240024002400240004000400040024242804240028294D29480428F9 +:201040002425240000000000000000000000000000000000000000002041A4C5E4E5E4C0EC +:20106000C4C0E4C1E4E5E8E9ECEDECEDF0F1F0EDF0EDF0CDECCDF1CDF0CDF0F1F5F1F5F5BE +:20108000F5D1D0D1F5F5F5F5F9F9F8F5F8D5F8D9F9F9F9F9F9FAF9F9F5F5F9F5F9FAF9FA11 +:2010A000F9FAF9D5F5F5F9F5F9FAF9FAF9DAD9DAFDFEFDFEFEFEFEDAB549242020000000FF +:2010C0002424242000000000242428492805040004042429482928242425484D4D4D2829BF +:2010E0000024000000000000000000000000000000000000000000242044A4C8C1E4C0C4AF +:20110000A0C4C0E4C0E4C4E8C9EDCDF1CDF1CDF1CDF1CDF1CDF1D1F1CDD1CDF5D1F5F1F57F +:20112000D1F1D1F5D1F5F5F9D5F9D5F9D5F9D5F9D5F9F9FDD9F9F9F9D5F5F5F9D5F9F9F93B +:20114000D5F9D9F9D5F9F9F9D5F9D9FDDAFEFAFEDAFEFEFEDAFEFEFEDAB1452400240024D7 +:201160000024242400000024004849714D4804280428284C284828480428296D4D4D294CCB +:201180004825240000000000000000000000000000000000000000002021A4A5C4C1C4C526 +:2011A000C4A0C0C1C0C5E8E9C8C9CCCDCCCDCCCDD1D1F1F2F5F2F6F6F5D2F1F2F1F1F5F2CD +:2011C000F0D1F0F1F0F1F4F5F4F5F9F9F8F9F9F9F8F9F9FAF9F9F9F9F4D5F5F5F4D5F5F5B7 +:2011E000F9F9F9D5F4F5F9FAF9D9F9FAFDFEFEFEFDDEFEFEFDFEFEFFFEDA914520002425B1 +:20120000242424250000240424284C71704D282828294C2928284829282528294C29282914 +:20122000926D25240000000000000000000000000000000000200020004481A9A0C4A0C4F0 +:20124000A0C0A0C0A0E4C5E8A5C8A9CDCDCDA9CDCDF5D2F6F6FAF7FBF6F6D2F5F1F5F1F5BF +:20126000CDF1CDF1CDF0D1F5D5F9D5F9F9F9D5F9D5F9F9F9D5F9F5F9D5F4D1F5D1F4D1F57D +:20128000D5F9F5F5D5F9D5F9D5D9D9FEFEFEDEFEDAFEDAFEFAFEFAFEDAFED6912424202432 +:2012A00024442424002400240448297151704C4C4C704D4C284C284C28480428282808289E +:2012C000DA6E2400000000000000000000000000000000000000000020218485A4A1A0A1D2 +:2012E000C0A1A0A0C0C1C4C5A8C9CDCED1CECDAED1D2F6F6FAFBFAFBFAFBF6D6F5F6F5D231 +:20130000F1CDF0EDF0F1F4F5F5F5F9F9F9F9F9D5F9F9F9F9F8F5F4F5F4F5F4F5F4F1F0F17A +:20132000F5F5F5F5F5F5F9F9D9D5D9FAFDFEFEFEFEFEFDFAFDFAF9FAFDFAFED690442424C1 +:2013400024252424240024042424284D7051505170717071704D4C29282928282828280480 +:201360006E490000000000000000000000000000000000240000002400244084808480A45E +:20138000A1C4A0C4A0A080A485CDCEF2D2D2D2F6D2F6D6FAD7FBDBFBDBFBFBFAD6F6F2F5E4 +:2013A000CDF1F1F5D1F5F5F9D5F9F5F9D5F9F5F9D5F9F9F9D5F5F1F4D1F5F5F9F1F1CDF09B +:2013C000CDF1F1F1D1F5D5F9D5F9FAFDDAFEFEFEDAFEFAFDDAF9F9F9DAFEFAFEDAB54844C1 +:2013E000244424440024042804284D7171714D707195959571702828042828280428040433 +:20140000240000000000000100000000000000000000000100000000000040416065A8892F +:201420008460A4A5A0A0A08184AED2D2D6D2F6F7D6D6D6D7D6D7DADBFAFBFAFBFAD7FAF74C +:20144000F5D2F5F2F5F5F5F6F5F5F9FAF9F5F5F5F4F5F9F5F4D5F4F1D0D1F4F1F0CDCCCDF3 +:20146000CCC9ECCDCCCDD0D1D0F5F9FAF9FAFEFEFDFAFDFAF5D5F5F5F9FAF9FAFDDAB169C4 +:20148000442424242424282948497091957170517075959695714C2928294C4D28240404E1 +:2014A00000000024000000000000000000000000000000240024002400240024208DB2D124 +:2014C0008584A0C4A0A480A485D1D2F6D2F6D7FBD6D692B26D9192DADBFFDBFBDBFAD7FACF +:2014E000F6F6F2F6F5F5D1F5D1F5D5F9F5F5D5F5F5F9F5F9F5F5D1F5D1F4F1F5F1F1EDF129 +:20150000C8ECC8ECCCECC9CCCCD0ADD1D1F5D6FED9FDFAF9D5D4D1F5D5F9D5F9DAFDD6B130 +:20152000244420240028244C484C4D7071704D504D95959975954D716D95929149480024E6 +:201540000000000000000000000000000000000000000000200000000000000048B6DAD7BC +:20156000D569A081A481808188CEF6F7F6D7D6D7FAD7B18E4869B6DBFAFBFAFBFADBFAFB23 +:20158000FAF7F5D6F5F2F1D1F5D5F5D1F5D1F4F5F9F5F9F5F5D1F0D1F4F1F0F1F0CDECCD08 +:2015A000ECCDCCCDF0F1F0F1F0F1F0D1F4F5F9FAF9FAF9F5F0D1F0F5F9F6D9D9F9FAFEB6CA +:2015C0004824200024212424282828494C4D504D5071959695717172959695714C28240558 +:2015E000002000000000002400000024000400000000002400200024002400286EFFDBFE85 +:20160000D6B185846084808465CDD2FAD7FAD7FAD7D6B2B66DB2D6FAD7FAD7FAD7FBFBFF40 +:20162000D7FAD6F6D1F5D1F5D1F5D1F5D1F5D5F9D5F9D5F5D1F5F1F5D1F5F1F0CDF0CDF0FC +:20164000CDF0D1F4D1F5F1F5CDF1D1F5D1F5D5F9D5F5F1F5CDF1D1F9D5F9D5F9D9FDDAB50B +:20166000244420240024002404282448284C4C704C7071957195719572957171282804287B +:201680000000000100000405040000000000000000000000000000012401244ADAFBFAFBDE +:2016A000DAD6CD856060808184A9D6F7FAD7FADBDAD7D6B7B5B6D6D7DAD7FAD7D6DBFAFB49 +:2016C000FAD7F6F6F5F2F5F6F5F5F5F6F5F5F9FAF9F5F5D5D4F5F5F5F0F1F4F1F4F1F5F5C9 +:2016E000F4F1F5F5F5F5F5F5F5D1F5F5F4F5F5D1F0D1F0F1F0F1F5F5F9F6F9FAF9FAD56968 +:2017000024242420200024242424242528284C4D504D5051707195767571704D280404045A +:2017200000200000002400240024002400240024002400040000002400242592DBFFDBFFD6 +:20174000D7FAD2AD606480A481C9B2F6D6FAD7FAD7DAD7DAB6DAB7DAD7FAB6D6B6FAD7FB5C +:20176000F6FAF6FAD5F5D5F9F5F9F5F5F5F5F5F9F5F9D5F5D1F5D1F5D1F0D1F5D5F9F5F9BA +:20178000F5F9D5F5D5F9F6F9F5F9F5F5F5F5D1F0CDF0CDF1F1F5D1F5F5F9D5F9F5F9B16867 +:2017A00024482024002400242024242400240448284C2C4C4C7071755170284C0424000446 +:2017C000000000000000000024252405240004002405240004000000000149B7FFDBFADB6E +:2017E000FADBFAD2A965808184A9B1D2D6D7DAD7DADBDADBDAD7D6D7DAD7D6D7D6DBFAFB5F +:20180000FAFBF9F6F5F6F5F6F9F6F5F6F5F6F5F6F5F6F5F5F5F5F4F1F0F1F4F5F5F5F9F914 +:20182000F9F6F5F5F9FAF9FAF9F6F5D1F0F1F0F1F0F1F0F1F5F5F5F5F5F6F5F5F5F5D169E3 +:201840002425442424202424242524202400040428292C284C4D70514C2D28282804040496 +:20186000000000240000002400242428002400240024042400040004002469FEDBFFFBFEB6 +:20188000DBFBF7FAAEAD818485CDB2F6B6DAD6FAD7FBDBFAD7DAD6DAB6D6D6FAD7FBFBFF97 +:2018A000D7FAF6FAD5F5F5F9D5F9F5F5D1F5D5F5D5F5F1F5D1F5F1F5D1F5D5F5D5F5D5F9E3 +:2018C000F5F9F9F9D5F9F9F9D5F5CDD0CDF0CDF5F1F5D1F5D1F5D1F5D1F5F5F9D5F5B18D8E +:2018E000496D6D8D2424002420442444002000240428284C284C4D4C2828284C24240428D7 +:20190000000000000000040524042425240424052404242524042401002591FBFADBFFDBDE +:20192000DADBFAFBD68E646564AED6D7D6D7FADBFADBDADBDAD7D6D7D6D7FAFBFAFBFFFB16 +:20194000FADAF9F6F5F6F5F6F5F5F5F6F1F1F5F6F5D1F4F1F0D1F0F1F4F5F5F5F4F5F5F658 +:20196000F9FAF9FAF9D5F5D5F0CDC8C9CCCDF0F1F4F1F0D1F0D1F0F1F0F1F5F6F5D5D5D698 +:20198000B5B6DAB66820242524242425240024052424282928292829040428292804242990 +:2019A000002000000024002404240424002400240024042404280024004892FFDBFEDBFFFF +:2019C000DBFEDBFBB26D4544458DB2D6D6FAD7FADBFADBFBDBFAD7FAD7FADBFFDBFFDBFF05 +:2019E000FAFAD6FAD5F5D5F5F5F5F1F5D1F5D1F5F1F5D1F1CDF0D1F5F1F5F1F5F1F5D5F988 +:201A0000D5F9FAF9F5F5EDF1C9ECC9ECCDF1D1F5F1F5D1F5F1F1CDF1D1F5D5F9D5F9DAFEC9 +:201A2000DBFEFBDA49240024244420240024002424280428242804040428294D494C284CFC +:201A40000000000000000001242524040400040424040404242524252449B5DBFADBDADBBF +:201A6000DADBDADB95494825244991B2D6D7DADBFADBFADBFADBFADBFADBFAFBFFFFFEFB8A +:201A8000FAFBF5F6F5F6F5F6F5F6F5F1F1F2F5F5F5F5F4D1F0F1F0F1F0F1F4F1F4F1F5F5EC +:201AA000F9F6F9F5F5D1ECC9E8E9ECEDF0F1F1F1F1F1F0F1F1F1F0EDF0F1F5F6F9FAFAFF27 +:201AC000FEFFFEB66C24242024242424240004042425242424040405484D5051714D6C7132 +:201AE000000000240000002400240024000400240024002400242428246DB6FADBFADBFE87 +:201B0000DBFBDBFA926D2548214969D6D7DAD7FBD7FADBFAD7FBDBFFDBFBFBFFDBFFFBFF8C +:201B2000F6FAF5F9D1F5F5F9D2F5F1F5D1F5D5F9D5F9F1F5D1F5D1F1CDF1F1F5D1F5D1F566 +:201B4000D5F5F1F5CDF1E9ECC9ECCDF1CDF1F1F5CDF1D1F5F1F5F1F1CDF1D5F9D6FAFAFE8B +:201B6000DBFEDADA8D8D696C496824480424042804282448252400484D717195727171BA7D +:201B80000000000000000001040424040400240524000001040424252449D6DBFADBFADBA9 +:201BA000FADBFADBB149482544456DB2DAD7DADBDADBFAFBFADBFEFBFAFBFFFFFEFBFAFBAD +:201BC000FAD6F5F6F5F5F5F6F5F6F5F6F5F2F5F6F9F5F9F6F5F1F0F1F0F1F5F1F0F1F5F19B +:201BE000F0CDCCCDECCDECE9E8E9F0F1F0F1F1F1F0F1F5F1F0F1F1F1F0D1F5F6F9FAFEFB6A +:201C0000FAD6FADBFAD6D6D6D5916C4524242829240424254425244971727576957299BA84 +:201C2000000000000000002400240024002400240024002400240024006DD6FADAFADBFA7A +:201C4000DBFADBFBB28D454945696AD6D6FAD7FAD7FADBFFDBFFDBFFDBFFDBFFDBFEDBFFB7 +:201C6000F6FAD6F5F5F5D5F5F5F5D2F5F1F5D5F9F9F9F5F9F5F5D1F5D1F5F1F5F1F5F1F18C +:201C8000CCCCC8CCC8ECC9ECC8ECCDF1CDF1CDF1CDF5D1F5D1F5D1F5F1F5D1F9DAFEFAFA31 +:201CA000D6FAD6FAFAFAD6FAD6D549442448244824280424244825484D917175719596BA49 +:201CC000000000000000000024052400040000000000000004000400246DDADBFADBFADBBB +:201CE000FADBFADBB66E694544498DB2DAFBFADBDAD7FAFBFAFBFADBFAFBFADBDADBFAFB0E +:201D0000FAF6F5D6F5F6F5F6F5F6F5F6F5F6F9FAF9FAF9FAF5D5F5F5F5F5F5F1F0F1ECCD7A +:201D2000CCCDECC9E8E9E8E9E8E9ECEDECCDD0F1F0F1F0F1F1D1F1F1F5F2F5F6FAFAFADA8F +:201D4000FAFAFAFBFADAD5D6D58D68446869484848242424484948294C6D71719596959605 +:201D6000000000240000002400240024000400040024002400040024006DD6FAD6FAD6FA7E +:201D8000DBFAD7FA928D6969254969B2B2FAFBFFD7FBDBFFDBFFDBFFDBFFDBFFD7FADBFEBF +:201DA000D6FAD6F9D1F5F5F5D1F5F5F5D5F5D5F9D5F9F9F9D5F5F5F9F5F5F1F5CDEDCDECD1 +:201DC000C8ECEDECE8E8C8E8C9ECC9ECC9ECCDF5D1F1D1F1D1F1D1F5D1F5D6FAD6FAFAFEAB +:201DE000FAFEFAFEFAFEFAF9D6F9B1B08DD18DB16D6C2448244C2848284C4D7571957195D5 +:201E00000000000000000000000000000000000000002425000004012069D6D7D6D7FADBBC +:201E2000FADBFAD7916969492425446991D7FFFBFADBFADBFAFBFFFBFAFBFFFFFAFBFAFB82 +:201E4000FAD6F5F6F5F6F5F6F5F2F5F6F5F6F9FAF9FAF9F6F5D1F5F6F5F5F5D1ECEDECED4C +:201E6000ECEDF0F1ECC9E8E9E8C9CCC9CCEDF1F1F0F1F1F1F1F1F1F1F1F2F5F6FADAFAFB23 +:201E8000FADAFAFBFEFAF9DAF9F6F5D1D1D1D5D6D9B28C4948484C4D4C4D5051704D4C4D93 +:201EA000000000000000000000000000000000000024002400040000006DB6FAD6FAD7FA18 +:201EC000D6FAD6B249482524002400446DDADBFFFBFFDBFFDBFFDBFFDBFFDBFFFBFFFBFB1B +:201EE000D6FAD6FAD5F9D2F5D1F5D1F5D5F9D5F9F5F9F5F5D1F1D1F5F5F5F1F1C9ECCDF1E6 +:201F0000D1F5F1F5EDECC9E8C8ECC9ECCDF1F1F5EDF1CDF1EDF1CDF1D1F5D6FADAFAD6FA0C +:201F2000DAFAD6FAFAFAD6FAF5F5D1F1D1F5D1F9FAFEB191486C4D704C704D704C70284CA9 +:201F40000000000000000000000000000000000000002400000000002069D6D7DAD7DAD7C5 +:201F6000DAD7B56D48452421242524256DB7FEFBFFFBFFFFFFFBFFFBFFFFFEFBFBFBFAFB3F +:201F8000FAD7F5F6F5F6F5F2F5F2F5F5F5D5F5D5F5F5F1D1F0CDF0F1F5F5F1D1ECEDF0F19E +:201FA000F4F5F5F5F1CDECC9ECEDECEDF0F1F1F1F0EDECEDF1EDD0CDF5F6FAFAFAFBFAFB6C +:201FC000FAD7D5D6F9FAF9D6F1CDCCCDF5F6F9FAF9FAD9D69471504D7071704D4C4D2828C3 +:201FE0000000000000000000000000000000000000000024000000240049B2FAD6FAD6FA04 +:20200000D6D6928D45482024002400242592DBFFDBFFDBFFDBFFFFFFDBFFDBFFDBFFFBFF37 +:20202000D7FAF6FAD6F9F5F5D1F5F1F5D1F5F1F5D1F1EDF1CDEDCDF1D1F5F1F1CDF1EDF172 +:20204000D1F5F5F5F1F1EDECC9EDEDF1CDF1CDF1CDEDC9EDCDF1CDF1D2FAD6FADBFFFBFFA9 +:20206000FBFAD1F5D5F9F1F5C9E8A9F1D1F5D6FADAFEFAFED6B56C6C4C7051702C4C284C74 +:202080000000000000000000000000000000000000000001000000000025B1D7D6D6FAD715 +:2020A000D6B6B16E6845442020202401246EDAFFFEFFFFFFFEFFFFFFFEDBFFFFFAFBFBFBDC +:2020C000FAFBFAFAF9F6F5F6F5F1F5F1F0F1F1F1F0EDF1EDECEDECF1F0F1F1F1F0EDF1F1BB +:2020E000F1F1F5F6F5D1ECEDECEDF1F1F0F1F0CDECEDECEDECEDF1F2F5F6FAFBFADBFEFBFF +:20210000FAD6F1D2F1D1F1CDC8C5CCF2F5F1F5FAFEFAFEFBD5B1906D4C4D4C4D4C28284DFD +:20212000000000000000000000000000000000000000000000000000002469D6D6D6D6DAE0 +:20214000B6B68E6D6588658444642524206DB7FFFFFFDBFFDBFFDBFFDBFFDBFFFBFFFBFBDE +:20216000FAFAD6FAF6F9F6F5F1F5F1F5D1F5D1F1EDF0E9EDC9ECCDF1CDF1CDF1EDF1EDF10F +:20218000D1F5D1F5F1F1CDEDCDF0CDF1F1F1CDCCC9EDE9EDEDEDCDF1CDF1D2FADBFEDBFFC0 +:2021A000FBFAD2D1CDF1C9C8A0E8C9F1CDF1D1FAFAFEDAFED6B18D8D4848244C2848246CFC +:2021C000000000000000000000000000000000000000000000000000000168B2D6D6D6D68C +:2021E000D6B28D498489A8A988654845486EDAFFFFFBFEDBFEDBFADBFADBFADBFAFBFAFB05 +:20220000FAFBFAF6F5F6F5F1F1F1F1F1F0F1F0CDECEDECE9E8E9ECEDECEDECEDECEDF0EDE6 +:20222000D0D1F5F5F1D1ECEDECEDECEDF1EDECC9ECEDECEDEDCDECC9CCC9D1F2FAFBFEFFC8 +:20224000FEDBF5D2F1EDECC5C4C5ECEDECCDF1F6F9FAF9FAF5B18C8D6C4428282824484DC7 +:20226000000000000000000000000000000000000000002000000000002025B1D6D6D6D6F0 +:20228000B2B28E6960A8A5A8658845684591B2DAD7FFDBFFDBFBDBFFDBFBDBFAD6FAD6FAE7 +:2022A000D6FAD6FAD6F5F1F5CDF1EDF1CDF1EDF1C9EDE9ECC9ECE9ECC9ECEDF1CDEDCDF175 +:2022C000CDF5F1F5CDCCC9ECCDF1CDF1EDEDC9ECC9EDCDF1CDEDC9EDC5E9CDF5D6FEFBFEDC +:2022E000DBFEF6F6EDF1E9ECC4E8E9EDC9EDCDF5D6F9F6FAD2D1ADB16D68284C28484C7037 +:2023000000000000000000000000000000000000000024000000000000002469B5D6D6D6D5 +:20232000B1928D658485A88564656849696A8D8E91B7FAFBFAFBFFFBDAD7DAD7D6D7FAFB9A +:20234000F6D6F5F6F5F6F5F2F0D1F1EDECEDECEDECEDECE9E8E9ECEDECC9ECEDECEDECED0B +:20236000F0F1F5F1ECC9E8E9ECEDF0EDECC9E8E9ECEDD1D2D1CEEDC9E8C9CDF2F9FBFEFBA6 +:20238000FAFBFAF7F1CEEDE9C4C5EDEDE8C9EDF2D5D6F5F6D5D2D1D2B18D4C4D4C4D70719E +:2023A000000000000000000000000000000000000024244400200000000000448DD6B2D642 +:2023C000B2B1696464A985884568496D496D4969458D92DADBFFDBFFD7DAD7DAD6FAF7FAD3 +:2023E000F6F6D6F5F1F5F1F5F1F1EDF1C9ECC9EDE9ECE9EDC9ECE9EDC9ECC9EDCDECCDF117 +:20240000F1F5F1F1C8C8C4E8C9ECEDF1C9E8C5EDCDF1ADD1ADD1CDCDC5E8C9F1D6FAFAFA43 +:20242000DAFEFBFAF2F1EDEDC4E8C9EDC9EDC9F1D1F5D1F5D2D5D2F6B5B56D704C7051955C +:202440000000000000000000000000000000000000254849240000000000002068B2D6B2E0 +:20246000B18E89656485686569696969696A69454445496EB1D7FAFBFADBDAD7D6D7F6D797 +:20248000F5F6F5F6F5F1F5F1F1F1ECEDECE9E8E9ECEDECEDECE9ECE9E8E9ECEDECEDECED81 +:2024A000F1F1ECCDC4C4C4C5E8E9ECEDE8C9E8E9CDCDADAED1D2F1CEE9C9EDEDF5FAFAFA7E +:2024C000FAFBFAFBF6D2F1CDC8C9E8C9E8E9ECEDF1F2F1F2F5D2D5F6F9B690494C4D4C4D8E +:2024E000000000000000000000000000000000000024454825240024000000242591B2B67C +:20250000AEAD898865896969496D49694969454945492544458D92D6D7FAD6D6B2D6D2D609 +:20252000D2F5F1F5D1F5F1F5F1F1EDECC9ECC9ECC9EDEDF1C9EDE9ECC9E8C9ECC9EDEDF104 +:20254000EDF1C9E8C4C4C4E8C4E8C9ECC9E8C9EDADCD8DB1B2F6F2F1C9EDCDF1D1F9D6F9A0 +:20256000D6FAFBFED6F6F1D1A5C8C9EDC5E9C9EDCDF5F1F5D6FAD6D5D6FA91682428284CD1 +:202580000000000000000000000000000000000000002425242024000000002124499192D9 +:2025A000AD8DA985698A6D6A6949484948454445444564454441446AB1B2D6D2D1B2D1D2FA +:2025C000D1D2F1F2F1F1F1F1F0EDF1EDECC9ECEDECEDECEDECCDECEDE8E9E8E9E8EDEDEDD3 +:2025E000ECE9E8C5C4A4C4C5C4C9E8E9ECC9CCEECDADB1B2D5D6F5F2EDCDF1F2F1F2F5F6C1 +:20260000F5FAFEFFFEDBFAD2C8C9E9E9C8C5C8CDF1EDF1F2D5F6D5B1D1D6D56D2424282415 +:20262000000000000000000000000000000000000000004425480024000000242469696D3E +:2026400089AD85A969AD6A6949492544454421442044456545442144458D8ED2B2D2AED113 +:20266000CDF1CDF1CDF1CDF1EDF1EDEDC9ECC9EDE9ECEDEDC9ECE9EDC4E8C4E8C8ECC9ED43 +:20268000E9ECC4C4A4A480A4A4C8C9EDCDF1CDF1ADD1AED6D6FAF6F5CDF1CDF1D1F5D1F50E +:2026A000D6FADBFEFBFEF6F6CDEDC9E9C5E8C9EDEDEDCDF1D1F5D2D1A9F1D6D56D4404249E +:2026C0000000000000000000000000000000000000002425484524000000000124496849E1 +:2026E0008889A8A9AD896945442120214445444144454445444544214445698EB1AECDCE66 +:20270000EDCDECEDECCDECEDF1EDECEDECEDE8E9ECEDECEDECE9ECC9C4C0C4C5E8E9E8C968 +:20272000E8C9C8A5848060608485A8A9CDCEF1D2D1AED1D2F5F6F5F2F1F2F1EDF1F2F5F181 +:20274000D5FAFEFBFEFBF9F6F1EDE8C9E8E9E8E9EDCDCCEDF1D2D1D2CDCED5D6B169242417 +:202760000024002400000004000000000000000000240048254824240000002420696D9141 +:2027800089ACC9EDA9A96564204020442044204421442144254425442144456869ADCDF125 +:2027A000CDEDEDF1C9EDC9F1EDF1EDEDC9EDC9ECE9EDE9EDC9ECE9E8A0C4C0E8C4E8C4E858 +:2027C000C5E8C9C860604064608889CDADD1D2F5CEF1D2F5D2F5D1F5F2F1EDF1CDF1D1F57C +:2027E000D5F9DAFEDAFAD2F5D1F1C9ECC5E9C9E9A9CDA9F1D2F6D2D1ADD1D1F5ADAD444420 +:2028000004000400000004000000000000000001240024252425442520002021448DD5D6AF +:20282000F1CDEDEDCDC9A9A984656441442124252425242524252425242544256489CDEE5E +:20284000ECC9ECEDECC9ECEDEDEDEDEDE8C9C8C9E8E9E8C9C8C9E8C9C4C0E4E5E4C4E4C504 +:20286000E8E9CCA9846064616485ACADADB2D1D2F1D2F1F2F1F2F5F2F1F1F1EDECEDF1F239 +:20288000F5F5F9FAF9D6F5D2F1D1EDC9C8C9C9EEF1CEF1F2F5F6F5B2ACD2F5D2ACAD884467 +:2028A000002404280448294824280004000000000024002400242548202420688DD5F6F5C9 +:2028C000F1F1E9EDC9E8A9C9A5A885894444214424442144244421242044204460A9C9EDD4 +:2028E000C9ECC9EDE9ECC9EDEDF1E9EDC9E8C4E8C8E8A0C4C4E8C9E8C4E4C5E8C4E4C4E8B7 +:20290000C8ECC9C86484608484A889CDADD1D2F5D1F1CDF1EDF1CDF1F1F1EDF1EDF1EDF147 +:20292000F1F5D1F9F6F9D2F1D1F1CDEDC5E8C9EDF2F6F2F1CDF1D2F5ADD1F2F1CDD1AD84D6 +:2029400028294C4D717271716C4D480400000000040424042424444548456891F5F6F5D18B +:20296000F1EDECC9C8C5A480A4A5A48564414420442540214421202044204040A4C9EDEDFE +:20298000E8C9ECEDEDC9E8E9EDEDECE9E8C5C4C5E8C5C4C4C4E9E8C9C4C5E4C5E4C5E4E50A +:2029A000E8E9CCA9A4858485A8A9CCCDD1D2F5F2F1CDECEDF1EDF0EDF1F1ECEDECEDECED6C +:2029C000F0F1F1F1F5F6F1D1ECEDEDC9C8C5C8E9EDCECDCDEDCDF1F2CDADF1F1CDCDD18978 +:2029E000719576997295717571914D4800000020000400240024206869B1D6FAD6F5F1F5AF +:202A0000EDF1EDECC9C880A480A4A5A460604044204440644040406440646084A5EDE9ED7D +:202A2000C4C4C9EDC9EDC9EDC9EDC9ECC5C8C4E8C4E4C4E4C4E8E9ECC5C4C0C4C0E4C4E81A +:202A4000C9EDC9C884A8A4C8A9CDC9CDA9F1D1F5EDF0C9ECC9EDCDF1CDF1EDECC9E8C9EC28 +:202A6000C9ECCDF1D1F5F1F1C9EDE9EDC5C8C5EDC9EDCDF1CDEDD1F5CDD1CDF1C9EDD1F1A8 +:202A80009596BA96959695769595954D24000001000000012420244991D6F9F6F5F6F5F27A +:202AA000F1CDEDEEEDC9C8A5A4A5C8C9C8A588856040606160618485848084A5C8E9EDE927 +:202AC000C4A0C8EDE8E9E8E9E8E9ECE9E8C4C4C5E8C5C8C5C4C5E8E9C4C5C4C5C4C4C8E981 +:202AE000E8C9C8C5A4A4C8C9C8C9EDC9C8C9F1EDECCDECE9ECE9ECEDECEDECC9C8C9E8E9DD +:202B0000ECEDF1EDF0F1F1EDECCDEDC5C4C5E8E9ECEDEDEEF1EDF1F2F1D1F1D2C8CDD1F129 +:202B20009ABA969A9699759571999671250400000000000000244491B6FAD6FAF5F5D1F575 +:202B4000EDF1CDF1EDEDC9EDC5E8C9EDC9EDA9A9646460846084808480A480C8C9EDC9E976 +:202B600084A4C5EDE9EDC9E9C9ECE9EDC4C4C4E8C5E8C5C8A0C4A4C8C4E8C5E4C4E8C4EC79 +:202B8000C9E8A5C8A4C8A5C8C9EDC9EDC9CCC9F1EDEDC9EDE9ECC9EDE9EDE9E8C4E8C9EC60 +:202BA000C9ECCDEDCDF1CDF1CDEDC9C8A0C4C5E9C9EDC9EDEDF1CDF1D1F1D1F1A8F0D1F5E3 +:202BC00099969576957695759596957148000000000000004469B1D6F9FAF9F6F5D2F1F26D +:202BE000F1CDECC9ECEDECC9ECC9C8C9EDEDCDA984606061808180808081A4A5E8EDCDA903 +:202C00008485C8C9E8E9E8C9E8EDEDC9C4A0C4C5E8E9E8C5A4A0A4A5C8C9E8C9C8C5C8C9B5 +:202C2000E8C5C4C5C4C5C8C9E8E9ECEDECC9C8C9ECE9E8C9E8E9E8E9ECE9E8C9E8E9E8E904 +:202C4000ECEDECEDECEDF0EDEDEDE8C5A0A0C4E9EDE9C8C9ECEDECEDF1F2F1D1CCCDF5F656 +:202C600075757575517575957195716C040400000000002469B5D6FAF6FAF6F9D5F5F5F520 +:202C8000CDEDC9ECC5E8C9EDC9EDC9E9C9EDC9C96060608460808080608080A8C9EDA9A81F +:202CA0004064A5CCC9EDE9EDC9EDEDEDA0A0A0C8C5E9C9C8A0A480C4A5E9E9ECC4C8C4E8D9 +:202CC000C5C8C4C8A4C8C4E8C9EDE9EDC9C8A4E8C9E8C5E8C5E8C9E8C9E8E8E8C4E8E8EC5D +:202CE000C9EDEDECC9F1EDF1CDF1E9C8A0A0C5E9C9E9C9E9C9EDCDF1CDF1D1F1C9EDD1F978 +:202D00007451747574717571714D4C250000000100000049B1D6F9D6D1D1D1D2F5F6F5D175 +:202D2000CCEDEDE9C8C5C8C9ECCDEDC9C8C9EDCAA88584618060806160606085A8A988617D +:202D4000404084A9C8C9EDC9E8E9E8C5A080A4C5C8C9C8A5C4A0A0A1A4C5E8E9C8C4C8E95E +:202D6000C8C5C4C5C4C5C8C9E8E9ECEDECC9C4C5C8C9E8C9E8C5E8C5E8C5E8E5E8E9E8E983 +:202D8000E8E9ECEDECEDEDEDEDEDEDC9C4A0C4E9E8E9E8C9ECEDF1EDECCDF1F2CCADD0F621 +:202DA000507451745150294C284804040000000000242091D6FAF6F5D1D1D1F5D5F9F1CD78 +:202DC000C9EDE9EDC9C8A5C9A9EDCDEDA5C8A9EDC9C98584608460806064406460844040EA +:202DE00020446088A5CDC5C9C5E8A5C480A080C4C9E8A0A4A4A480A080C8C5E9C4C8C5E881 +:202E0000C4C4A0C4A4C8C5C8C8ECC9EDE9E8A0C4C4E8C5E8C4E8C4C4C4E8C4E8C4E8C9E8EC +:202E2000C8ECC9EDCDEDCDEDCDF1EDEDC5C4A1E9C5E9C9EDCDF1CDF1CDF1D1F5ADAC69D50E +:202E400074717451702D28040400000000000000000068D6FAFAF5F6F5F2F5F6F5F2F1C96B +:202E6000E8E9E8E9E8C5A4A5A8A9EDCDC9A5A8A9CDC9A885848180606060404060604040C8 +:202E800040406465A4A5C8C5C4A5C8A5808080A5C8C5A480A4A5A08080A5C4C9C8C5C4C536 +:202EA000A4A0A4A5A4C5C8C5C8C9E8C9E8C5A4A0C4C5C4C5C4A5C4C5C4C5E4C5E8E9E8E984 +:202EC000E8E9ECEDECEDECEDEDEDEDEDEDC9C4C5E8E9E8E9ECCDCCC9ECEDF1F1AD89486D0D +:202EE0005074507471500404000000200000000000248DFAD6D5D1F5D2F6D6F9F2F1EDEDF1 +:202F0000C5E8C5E8C9C884A465A9C9EDA9C985A485C9A9A88084608460644064406440600C +:202F20004044406480A8A5C8A0A4A5C8808080A4A5C480A480A480A480A4A0C8A5C4A4C4CD +:202F400080A4A0A4A0C4A4C8A4C8C5E8C5C4A0C4A0C4A0C4A0C4A0C4C4E8C4E8C4E8C8ECEB +:202F6000C9ECEDEDCDEDEDF1CDEDCDF1E9EDC5E8C5E9C9EDC9CCA8CCC9ECCDF18DB12448A5 +:202F800074717475956D280400000000000000002069D5D6D1ADADCED1D2F5F6F1CDEDE9E6 +:202FA000C8C5C8C9E8C9A8856485A9CECDC9A8858485A8858080808164606441404064610D +:202FC000444040408485C8A5A0A0C4A580808080A480A48080A5A4818080A4A5A4A0A4A06B +:202FE0008080A4A5A4A4A4A5A4A5C4A5A4A0A4A0A0A0A4A5A4A0C4C5C4C4C4C5E8C9E8E9D4 +:20300000E8E9ECEDECEDECEDECC9ECC9EDE9E8C5C8C5C8C5C8C9CCC9C8C9CDCDB1B26C2508 +:203020005175719571712524002400240024002020D1D2AD84A8C9F1ADD1D1F1C9EDC9E90F +:20304000A4C8A5EDCDEDA9A4648885ADC9CD89844464606480A48084606440644064606446 +:203060004064204464A885A480A4A5A8808480A480A48080608480846084808080A480A442 +:2030800080A480A480A480A480A480A480A480A4A0C4A4C4A4C8A4C8A4C4C4E8C9E8E9ECD2 +:2030A000E9ECC9EDC9ECC9EDC9EDC9E9C9EDC9E9A5C88584A9EDC9EDC9ECCDF1B1F56E48B9 +:2030C0004C4D4C4948292400040004000001000068D2ADA9CDCDEDC9C8C9EDCDE8E9ECC973 +:2030E000A8A5C8CDF1CDCDA564656485A9A9896564416061808184606440604060616460B8 +:2031000064614040648584848080A4A584808480848180808060848080808080808080803F +:20312000A4A5A480808080808480A080A4A0A4A5C4C5C4C5C8C9E8C9C8C5C4E9E8E9E8E941 +:20314000E8E9E8E9ECE9ECEDECE9E8C9E8E9E8C9A8A5A485C8CDECC9E8E9ECEDD1D6B54908 +:203160000024002400240424000404240024004489D1CDF1F2F1C9C8A5EDE9EDC5C8A9CD30 +:203180008988A4CDCDEDC9C985846488658965682044406460646084404440644064608451 +:2031A0006064406460848484608480A460848084608460846060608460848084808480A44F +:2031C00080A484A4608080A480A480A480A4A4C8A4C8C4E8C5E8E9ECC5E8C5ECE9E8E9EC29 +:2031E000C9E8E9ECC9ECE9ECC9EDE9ECC5E8E9EDA5A4A9ADA9F1C9C8C9ECCDF1ADD1B668D8 +:2032000000000400244948292404240520002045D1D2F5F6F1CEE9C9E8EDEDE9C4A084A9BB +:20322000A86584A9C8A9C9C9A88584654440442540206465646064654440444564608461E2 +:20324000606060616065848584608481806080806060606060606461846084808080A4A520 +:20326000A4A5A480808080808080A4A4A4A5C8C5C8C9E8E9E8E9ECE9E8C9E8E9E8E9ECE993 +:20328000E8E9E8E9E8E9E8E9E8E9E8E9C8C5E8E9C880A8A9CCCDCDA9A8CDECF1B1B2DA496A +:2032A0000428254D4D914D4D28280424002441ADD2FAF6F6CDA9A5C9EDF1C9EDA5A4608411 +:2032C0006484608484A4A5C9A5C485842040204420444068646460644464406460846084AA +:2032E0006084606060846584848460846084608060806064606460846084808480A480A431 +:20330000A4A480808084808480A4A0A4A4C8C4E8C4E8C9E8C8ECE9ECC8E8C5E9E9E8E9EDF2 +:20332000E9E8C9E8E9ECE9E9C9E8C9E8C5E8C5E9C9A484A8A9F1ADA884ACCDF5B1D1D66D68 +:2033400071729596B5969576714D2804202588D2F5F6F5D2A86184A9F1F2EDCDCDCDAC892C +:2033600084858484A484A4C5C8A5A885644044454040406584648464646464648461848472 +:2033800084606060606184858460606060616060806060606060606084818480A484A4A500 +:2033A000A48480808081A480A4A5C4C5C4C5C8C5E8E9E8E9E8E9E8E9E8E9E8E9E8E9E8E950 +:2033C000E8E9E8E9E8E9E8E9E8E9E8E9E8E9E8C9C8A58485A8ADAD896889D1D2B1B2DA6D46 +:2033E00096B996BA96BA9ABA96954D482068ADF6D2F6D1A86084A5EDCDF1CDF1CDF1EDCDF4 +:20340000A5CDA9C8A5A480C8A5C484A8656464644040408860848084608460846084608452 +:20342000606460644064608460846060406460846084608460806084608480A480A480A474 +:2034400080A480A480A4A4C8A4C8C4E8C5E8C4E8C4E8C4E8C5E8C9ECC9E8C4E8C5E8E9EC8A +:20346000C9E8C9ECC9E8C5E8C5E8E9E8E5E8C9E8C5C480A484AD8E8D6991B1D16EB2B66DD4 +:20348000717195969596999A99969149446DF5F6F5D2A8616085CDEEF0CDEDEDEDEDF1ED5D +:2034A000C8C9EDC9C8A5A4A1A4A5848584658465604064658480A480848084818460848568 +:2034C000646060406060848180806060606184618060806180608060808080808080A081BB +:2034E0008080A4A5A4A5C8C5C8C5E8E9E8C5E8E9E8E5E8E9E8C9E8E9E8C5E8E9E8E9E8E991 +:20350000E8C9ECE9E8C5E8E9E8C9E8E9E8E9E8E9E8C5A4A584A98D8E6D6EB18E6D8E966E2C +:2035200051745174517471957195514C4891D2F5CDC8808484CDCDEDC9EDC9EDEDEDCDED4F +:20354000C9EDC9E9A9A8808480A480A4848464644064608480A480A4808460846084608416 +:20356000406440646084608460846060608480846084608480A46084808480A080A480A473 +:2035800080A4A0C8A4C8C5C8C4E8C5E8C5E8C5E8C4E8C5E8C9ECC9E8C5E8C5E8C5E8C9ED77 +:2035A000C9ECC9EDC9E8C5E8C5E8C5E9E9E8E5E8C5E8A1C88588456E6E926E6E4A92926DBC +:2035C00050515051705170717171502D4C6DACADC8A58485A8CDEDEDEDE9E8C9ECC9EDEDBB +:2035E000EDEDE8C9C8858484A4A5A4A4848464606460646584848480848084808460646441 +:203600006440404060608080848160608081848180618480A0808080808080808080A080D6 +:20362000A4A5A4A5C8C5C8C5C8C9E8C9E8E9E8E9E8C5E8C9E8E9E8E9E8E9E8E5E8E9E8E9BA +:20364000E8E9ECE9E8C9E8C5E4C5E8E9E8E9E8E9E8C5A4A58865496E7293926E6D6E914AF5 +:203660002D504C504D504D704D702C4C284C89CDA5A484C8A9EDC9EDC9EDE9ECC9E8CDF1FD +:20368000EDEDC9C8A5A460A484C8A5C884A4608460646084808480A4808480846080608411 +:2036A000406040644060608460846084608484A4608480A480A480A480A080A480A480A492 +:2036C00080A4A4C8A4C8C4E8C5E8C4E8C5E8E5E8C5E8C4E8C5E8C5E8C5E8C5E8C5E8E9ECE0 +:2036E000C9E8E9ECC9E8C5E8A0C4C4E8C5E8E9ECC9C480A46588256D6F9793924A926E4966 +:203700005051504D2828282928294C4D4848ACCDC8A5C8C9CDCDEDEDEDEDEDE9E8C9ECED2B +:20372000ECC9C8C5A4808485A4A9C8C9A8A58480606060608480A481808084818060646198 +:203740004040404040408081808084818081A4856060A485A080A4818080A481A080A4A101 +:20376000A4A0A4C5C4C5C8C5C4C5E8C5E8C5E8E9E8E5E8E5E4C5E8E9E8E5E8E5E4E5E8E98A +:20378000E8E9ECE9E8E9E8C5C4A0C4E5E8E9E8E9C8A080816465494A727396934D6F922A0B +:2037A0007195714D242404240428284C486CADD1A5C8A9EDCDEDC9EDEDEDE9EDC9E8C9ED79 +:2037C000E9ECC5C8A4A4608484C8C5EDC9C88584608060806084808480846084808060646F +:2037E00040644044406460846084608480A48584608480A480A480A480A480A480A480A444 +:2038000080A4A0C8C4C8C5E8C4E8C4E8C4E8C5E8E4E8C5E8C4E8C5E8C4E8C5E8E4E8E5E86E +:20382000C9ECC9ECE9ECC9C8A0C4A0E4C5E8C5C8A4A46084648825694E9673934A92934D4A +:20384000999A954D2804242524252828686DCDADA8C9CCEEF1EDEDCDEDCDECC9E8C9C8C982 +:20386000ECE9C8C9C885806084A5C8C9C8C9A48080808060808184808080808080606060C1 +:20388000404040404041806180808080A4A584606081A485A4A4A4A0A4A0A4A0A0A1A0A0FA +:2038A000A4A0A4A5C4C5C4C5C4C5C4C5C4C5C4C5E4E5E8E5E8E9E8E5E8E5E4E5E8E5E8E9DD +:2038C000E8E9E8E9ECE9E8C5C4A0A0C5C4C5C4A5A48160608465494A4E7392734E6F964E41 +:2038E00071959671292824280428244844B1CDCDA5CDCDF1CDF1EDEDA5C8C9E9C5E9C4C8D6 +:20390000C5E8C5E8A5A4808480A4A4C8A5C8A4A460806080608480846080608460804064CB +:2039200040404044406460846080808480A48080608480A480A4A0A480A4A0A480A480A4D3 +:2039400080A4A0C4A0C4C4C4A0C4C4C4A0C4C4E4C4E8C5E8C5E8E9E8C5E8E4E8C5E8E9E82D +:20396000C9E8E9ECC9EDC9C8A0A4A0C4C4C4A4C460846084608845694A7273724A72976E22 +:203980004C4D7172916D4C292404242568ADD1ADC8CDEDEEF0CDF1CDA485C4A5C4C5C8A5C1 +:2039A000A4C5C8C9C8A584858080A4A5A4A5A481808080818060848160606461646064410C +:2039C000402040414040806180808081A4A584608085A4A5A480A4A5A4A0A4A1A0A0A0A1B2 +:2039E000A4A0A4A1A4A1C4C5A4A0C4C5C4C5C4C5C4C5E8E9E8E9E8E9E8E5E8E5E8E5E8E95D +:203A0000E8E9E8E9ECE9E8C5A4A0C4C5C4C5A4A580808461848569664E7372734E4E964A04 +:203A2000285071BAB6BA926D2424004488D1ADADA9F1CDF1CDF1CDCD84A480A4A0E8C5C428 +:203A4000A0C4C5E9A9C885A480A480A480A480A480846084608460846064406460644064AA +:203A60002040204040646084608060A480A4608060A4A5A480A480A4A0A4A0A4A0A480A491 +:203A8000A0A4A0A4A0C4A0C4A0C4A0C4A0C4A0C4C4E8C5E8C5E8E9E9E5E8C5E8C4E8C5E89B +:203AA000E9E8C9E8C9ECC5C4A0C4A0C4C4E4A5C48084608484A865694A7273734A6E734975 +:203AC000507195BABABBBA7248042025ACD2ADADADD2EDCDECCDCCA98885A485A4C5E8C519 +:203AE000C4C5C8C9A8A9A8A5A4A5A4A4A48080808480808080808060604040406061444010 +:203B0000202020206061808180608081A4A180608485A4A5A4A5A4A0A4A1A0A0A4A0A4A071 +:203B2000A4A1A0A0A4A1A4A1A4A1A4A0C4A1C4C1C4C5E8C5E8E9E8E9E8E5E8E5E8C5E8E913 +:203B4000E8E9E8C9E8E9C8C5C4C5C4C5E8C5C4C5A4808081848564654E7372734E4A922650 +:203B6000719596BA96BAB69529240048ADD58DD18EB2A9ADA5C9A9A8648884A8A0C4A4C8A2 +:203B8000C5C8C9C8A9A8A5A8A4A8A4A480A4608480848084608460844060404440642040D5 +:203BA0000020002440646084608480A480A0608480A4A5C8A5C4A4A4A0A4A0A480A4A0C4DB +:203BC000A0A4A0A480A4A0C4A0C4A0C4A0C4A0C4C0E8C5E8C5E8E5E8C5E8C4E8C5E4C4ECC4 +:203BE000C9E8C9E8C9E8C5C4A0C4C4E8C5E8C5E8A0A0608480A865892A7273724A4E7349B0 +:203C0000747175769596956E28002049B1B2B1B2928E8965646584658489A8A5A4A5C4C563 +:203C2000E8C5C8C9A889A8A9A4A5A8A5A4848060806084808080846160404040404020207D +:203C400020202020606184656060A4A5A4808485A4A5C4C5C4A5C4A1A0A0C4A1A0A0A4A13A +:203C6000A4A0A4A1A0A0A4A1A0A0C4A1C4A1C4C5C4C5E4E5E4C5E8E5E4C5E4E5E4C5C4E913 +:203C8000E8E9E8E9E8C9C8C5C4C5E8E9E8C5E8C5C4808485A4A589654D6F72734E4A922A17 +:203CA0005074517571956D4C042400488DB192B66E6E6A452044406464A885A4A4C8A5E903 +:203CC000EDE8A4C884A885A884A884A884A460846084608480A4608460844060204400200E +:203CE0002020204460846164608485A4A0A480A4A0A4A5C8A5C4A1A4A0C4A0C4A0C4A0A433 +:203D0000A0C4A0A4A0A4A0A4A0C4A0C4A0C4A0C4C4E4C5E8C4E8C5E8C4C4C4E8C4E8C4E8A9 +:203D2000E9E8C9E8C9E8C5A4A0C4C5E9E9E8C5E9C5C480A4A4A865854A9273724A6E6F4A41 +:203D400050517051714D4824040000256D729697726F69254445644584858480A4C9E8E9B6 +:203D6000EDC9A8A588858889A885A4848484646084608480848180808461644040412020CA +:203D800020204041646564658485A4A5A0A1A4A5A4A5C4C5C4A5A4A1A4A1A4A0A4A1A4A062 +:203DA000A4A0A0A0A0A1A0A1A0A1C4A1C4C1C4C5C4C5C4C5E4C5C4C5C4C5C4C5E8C5C4C5BD +:203DC000E8E9E8C5E8E9C4A0A0C5E8E9E8E9E8E9C8A5A4A5C8A584856D6F726F4E4A722A3B +:203DE000507451702D28042800240024259297B66F724A49458D898880848084A0E9E9EDB3 +:203E0000CDEDA9A8648884A884A884A484846484608480846084608460846064204020441F +:203E2000204040646084648885A8A4A4A0C4A4A4A0A4A0C4A0C4A0C4A0C4A0C4A0C4A0C48D +:203E4000A0A4A0C4A0A4A0C4A0C4A0C4A0C4C0C4A0C4C4E8C4E4C4E8C5E4C0C4C4E4C4E481 +:203E6000C0E4C4E8C5E8A4A480C4C9EDE9E9E9E8C5C4A0C8A5C885A94A6E73724A4E6E4DE4 +:00000001FF diff --git a/tutorials/soc/lesson12/image.png b/tutorials/soc/lesson12/image.png new file mode 100644 index 0000000..3bd7739 Binary files /dev/null and b/tutorials/soc/lesson12/image.png differ diff --git a/tutorials/soc/lesson12/image.qip b/tutorials/soc/lesson12/image.qip new file mode 100644 index 0000000..2693b8e --- /dev/null +++ b/tutorials/soc/lesson12/image.qip @@ -0,0 +1,3 @@ +set_global_assignment -name IP_TOOL_NAME "ROM: 1-PORT" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "image.v"] diff --git a/tutorials/soc/lesson12/image.v b/tutorials/soc/lesson12/image.v new file mode 100644 index 0000000..5a4b7ea --- /dev/null +++ b/tutorials/soc/lesson12/image.v @@ -0,0 +1,164 @@ +// megafunction wizard: %ROM: 1-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: image.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.4 Build 182 03/12/2014 SJ Web Edition +// ************************************************************ + + +//Copyright (C) 1991-2014 Altera Corporation +//Your use of Altera Corporation's design tools, logic functions +//and other software and tools, and its AMPP partner logic +//functions, and any output files from any of the foregoing +//(including device programming or simulation files), and any +//associated documentation or information are expressly subject +//to the terms and conditions of the Altera Program License +//Subscription Agreement, Altera MegaCore Function License +//Agreement, or other applicable license agreement, including, +//without limitation, that your use is for the sole purpose of +//programming logic devices manufactured by Altera and sold by +//Altera or its authorized distributors. Please refer to the +//applicable agreement for further details. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module image ( + address, + clock, + q); + + input [13:0] address; + input clock; + output [7:0] q; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [7:0] sub_wire0; + wire [7:0] q = sub_wire0[7:0]; + + altsyncram altsyncram_component ( + .address_a (address), + .clock0 (clock), + .q_a (sub_wire0), + .aclr0 (1'b0), + .aclr1 (1'b0), + .address_b (1'b1), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clock1 (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_a ({8{1'b1}}), + .data_b (1'b1), + .eccstatus (), + .q_b (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_a (1'b0), + .wren_b (1'b0)); + defparam + altsyncram_component.address_aclr_a = "NONE", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_output_a = "BYPASS", +`ifdef NO_PLI + altsyncram_component.init_file = "image.rif" +`else + altsyncram_component.init_file = "image.hex" +`endif +, + altsyncram_component.intended_device_family = "Cyclone III", + altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 16384, + altsyncram_component.operation_mode = "ROM", + altsyncram_component.outdata_aclr_a = "NONE", + altsyncram_component.outdata_reg_a = "UNREGISTERED", + altsyncram_component.widthad_a = 14, + altsyncram_component.width_a = 8, + altsyncram_component.width_byteena_a = 1; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: AclrAddr NUMERIC "0" +// Retrieval info: PRIVATE: AclrByte NUMERIC "0" +// Retrieval info: PRIVATE: AclrOutput NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: Clken NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "image.hex" +// Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "16384" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: RegAddr NUMERIC "1" +// Retrieval info: PRIVATE: RegOutput NUMERIC "0" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: SingleClock NUMERIC "1" +// Retrieval info: PRIVATE: UseDQRAM NUMERIC "0" +// Retrieval info: PRIVATE: WidthAddr NUMERIC "14" +// Retrieval info: PRIVATE: WidthData NUMERIC "8" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: INIT_FILE STRING "image.hex" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "16384" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM" +// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "14" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: USED_PORT: address 0 0 14 0 INPUT NODEFVAL "address[13..0]" +// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" +// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]" +// Retrieval info: CONNECT: @address_a 0 0 14 0 address 0 0 14 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 +// Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL image.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL image.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL image.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL image.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL image_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL image_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/tutorials/soc/lesson12/img2hex.sh b/tutorials/soc/lesson12/img2hex.sh new file mode 100755 index 0000000..d1af36f --- /dev/null +++ b/tutorials/soc/lesson12/img2hex.sh @@ -0,0 +1,4 @@ +#!/bin/bash +avconv -vcodec png -i image.png -vcodec rawvideo -f rawvideo -pix_fmt rgb8 image.raw +srec_cat image.raw -binary -o image.hex -intel + diff --git a/tutorials/soc/lesson12/osd.v b/tutorials/soc/lesson12/osd.v new file mode 100644 index 0000000..a654b40 --- /dev/null +++ b/tutorials/soc/lesson12/osd.v @@ -0,0 +1,182 @@ +// A simple OSD implementation. Can be hooked up between a cores +// VGA output and the physical VGA pins + +module osd ( + // OSDs pixel clock, should be synchronous to cores pixel clock to + // avoid jitter. + input pclk, + + // SPI interface + input sck, + input ss, + input sdi, + + // VGA signals coming from core + input [5:0] red_in, + input [5:0] green_in, + input [5:0] blue_in, + input hs_in, + input vs_in, + + // VGA signals going to video connector + output [5:0] red_out, + output [5:0] green_out, + output [5:0] blue_out, + output hs_out, + output vs_out +); + +parameter OSD_X_OFFSET = 10'd0; +parameter OSD_Y_OFFSET = 10'd0; +parameter OSD_COLOR = 3'd0; + +localparam OSD_WIDTH = 10'd256; +localparam OSD_HEIGHT = 10'd128; + +// ********************************************************************************* +// spi client +// ********************************************************************************* + +// this core supports only the display related OSD commands +// of the minimig +reg [7:0] sbuf; +reg [7:0] cmd; +reg [4:0] cnt; +reg [10:0] bcnt; +reg osd_enable; + +reg [7:0] osd_buffer [2047:0]; // the OSD buffer itself + +// the OSD has its own SPI interface to the io controller +always@(posedge sck, posedge ss) begin + if(ss == 1'b1) begin + cnt <= 5'd0; + bcnt <= 11'd0; + end else begin + sbuf <= { sbuf[6:0], sdi}; + + // 0:7 is command, rest payload + if(cnt < 15) + cnt <= cnt + 4'd1; + else + cnt <= 4'd8; + + if(cnt == 7) begin + cmd <= {sbuf[6:0], sdi}; + + // lower three command bits are line address + bcnt <= { sbuf[1:0], sdi, 8'h00}; + + // command 0x40: OSDCMDENABLE, OSDCMDDISABLE + if(sbuf[6:3] == 4'b0100) + osd_enable <= sdi; + end + + // command 0x20: OSDCMDWRITE + if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin + osd_buffer[bcnt] <= {sbuf[6:0], sdi}; + bcnt <= bcnt + 11'd1; + end + end +end + +// ********************************************************************************* +// video timing and sync polarity anaylsis +// ********************************************************************************* + +// horizontal counter +reg [9:0] h_cnt; +reg hsD, hsD2; +reg [9:0] hs_low, hs_high; +wire hs_pol = hs_high < hs_low; +wire [9:0] h_dsp_width = hs_pol?hs_low:hs_high; +wire [9:0] h_dsp_ctr = { 1'b0, h_dsp_width[9:1] }; + +always @(posedge pclk) begin + // bring hsync into local clock domain + hsD <= hs_in; + hsD2 <= hsD; + + // falling edge of hs_in + if(!hsD && hsD2) begin + h_cnt <= 10'd0; + hs_high <= h_cnt; + end + + // rising edge of hs_in + else if(hsD && !hsD2) begin + h_cnt <= 10'd0; + hs_low <= h_cnt; + end + + else + h_cnt <= h_cnt + 10'd1; +end + +// vertical counter +reg [9:0] v_cnt; +reg vsD, vsD2; +reg [9:0] vs_low, vs_high; +wire vs_pol = vs_high < vs_low; +wire [9:0] v_dsp_width = vs_pol?vs_low:vs_high; +wire [9:0] v_dsp_ctr = { 1'b0, v_dsp_width[9:1] }; + +always @(posedge hs_in) begin + // bring vsync into local clock domain + vsD <= vs_in; + vsD2 <= vsD; + + // falling edge of vs_in + if(!vsD && vsD2) begin + v_cnt <= 10'd0; + vs_high <= v_cnt; + end + + // rising edge of vs_in + else if(vsD && !vsD2) begin + v_cnt <= 10'd0; + vs_low <= v_cnt; + end + + else + v_cnt <= v_cnt + 10'd1; +end + +// area in which OSD is being displayed +wire [9:0] h_osd_start = h_dsp_ctr + OSD_X_OFFSET - (OSD_WIDTH >> 1); +wire [9:0] h_osd_end = h_dsp_ctr + OSD_X_OFFSET + (OSD_WIDTH >> 1) - 1; +wire [9:0] v_osd_start = v_dsp_ctr + OSD_Y_OFFSET - (OSD_HEIGHT >> 1); +wire [9:0] v_osd_end = v_dsp_ctr + OSD_Y_OFFSET + (OSD_HEIGHT >> 1) - 1; + +reg h_osd_active, v_osd_active; +always @(posedge pclk) begin + if(hs_in != hs_pol) begin + if(h_cnt == h_osd_start) h_osd_active <= 1'b1; + if(h_cnt == h_osd_end) h_osd_active <= 1'b0; + end + if(vs_in != vs_pol) begin + if(v_cnt == v_osd_start) v_osd_active <= 1'b1; + if(v_cnt == v_osd_end) v_osd_active <= 1'b0; + end +end + +wire osd_de = osd_enable && h_osd_active && v_osd_active; + +wire [7:0] osd_hcnt = h_cnt - h_osd_start + 7'd1; // one pixel offset for osd_byte register +wire [6:0] osd_vcnt = v_cnt - v_osd_start; + +wire osd_pixel = osd_byte[osd_vcnt[3:1]]; + +reg [7:0] osd_byte; +always @(posedge pclk) + osd_byte <= osd_buffer[{osd_vcnt[6:4], osd_hcnt}]; + +wire [2:0] osd_color = OSD_COLOR; +assign red_out = !osd_de?red_in: {osd_pixel, osd_pixel, osd_color[2], red_in[5:3] }; +assign green_out = !osd_de?green_in:{osd_pixel, osd_pixel, osd_color[1], green_in[5:3]}; +assign blue_out = !osd_de?blue_in: {osd_pixel, osd_pixel, osd_color[0], blue_in[5:3] }; + +assign hs_out = hs_in; +assign vs_out = vs_in; + +endmodule \ No newline at end of file diff --git a/tutorials/soc/lesson12/rgb2ypbpr.sv b/tutorials/soc/lesson12/rgb2ypbpr.sv new file mode 100644 index 0000000..1e1662e --- /dev/null +++ b/tutorials/soc/lesson12/rgb2ypbpr.sv @@ -0,0 +1,55 @@ +module rgb2ypbpr ( + input [5:0] red, + input [5:0] green, + input [5:0] blue, + + output [5:0] y, + output [5:0] pb, + output [5:0] pr +); + +wire [5:0] yuv_full[225] = '{ + 6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1, + 6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4, + 6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6, + 6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8, + 6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11, + 6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13, + 6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15, + 6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17, + 6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20, + 6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22, + 6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24, + 6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27, + 6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29, + 6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31, + 6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33, + 6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36, + 6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38, + 6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40, + 6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42, + 6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45, + 6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47, + 6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49, + 6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52, + 6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54, + 6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56, + 6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58, + 6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61, + 6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63, + 6'd63 +}; + +wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0}); +wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0}); +wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0}); + +wire [7:0] y_i = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8]; +wire [7:0] pb_i = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8]; +wire [7:0] pr_i = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8]; + +assign pr = yuv_full[pr_i - 8'd16]; +assign y = yuv_full[y_i - 8'd16]; +assign pb = yuv_full[pb_i - 8'd16]; + +endmodule diff --git a/tutorials/soc/lesson12/scandoubler.v b/tutorials/soc/lesson12/scandoubler.v new file mode 100644 index 0000000..6edcc8d --- /dev/null +++ b/tutorials/soc/lesson12/scandoubler.v @@ -0,0 +1,147 @@ +// +// scandoubler.v +// +// Copyright (c) 2015 Till Harbaum +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +module scandoubler ( + // system interface + input clk_in, + input clk_out, + + input scanlines, + + // shifter video interface + input hs_in, + input vs_in, + input [5:0] r_in, + input [5:0] g_in, + input [5:0] b_in, + + // output interface + output reg [5:0] r_out, + output reg [5:0] g_out, + output reg [5:0] b_out, + output reg vs_out, + output reg hs_out +); + +// scan doubler output register +reg [17:0] sd_out; + +// --------------------- create output signals ----------------- +// latch everything once more to make it glitch free and apply scanline effect +reg scanline; + +always @(posedge clk_out) begin + vs_out <= vs_in; + hs_out <= hs_sd; + + // reset scanlines at every new screen + if(vs_out != vs_in) + scanline <= 1'b0; + + // toggle scanlines at begin of every hsync + if(hs_out && !hs_sd) + scanline <= !scanline; + + // if no scanlines or not a scanline + if(!scanlines || !scanline) begin + r_out <= { sd_out[17:12] }; + g_out <= { sd_out[11:6] }; + b_out <= { sd_out[5:0] }; + end else begin + r_out <= { 1'b0, sd_out[17:13] }; + g_out <= { 1'b0, sd_out[11:7] }; + b_out <= { 1'b0, sd_out[5:1] }; + end +end + + + +// ================================================================== +// ======================== the line buffers ======================== +// ================================================================== + +// 2 lines of 1024 pixels 3*6 bit RGB +reg [17:0] sd_buffer [2047:0]; + +// use alternating sd_buffers when storing/reading data +reg vsD; +reg line_toggle; +always @(negedge clk_in) begin + vsD <= vs_in; + + if(vsD != vs_in) + line_toggle <= 1'b0; + + // begin of incoming hsync + if(hsD && !hs_in) + line_toggle <= !line_toggle; +end + +always @(negedge clk_in) begin + sd_buffer[{line_toggle, hcnt}] <= { r_in, g_in, b_in }; +end + +// ================================================================== +// =================== horizontal timing analysis =================== +// ================================================================== + +// total hsync time (in 16MHz cycles), hs_total reaches 1024 +reg [9:0] hs_max; +reg [9:0] hs_rise; +reg [9:0] hcnt; +reg hsD; + +always @(negedge clk_in) begin + hsD <= hs_in; + + // falling edge of hsync indicates start of line + if(hsD && !hs_in) begin + hs_max <= hcnt; + hcnt <= 10'd0; + end else + hcnt <= hcnt + 10'd1; + + // save position of rising edge + if(!hsD && hs_in) + hs_rise <= hcnt; +end + +// ================================================================== +// ==================== output timing generation ==================== +// ================================================================== + +reg [9:0] sd_hcnt; +reg hs_sd; + +// timing generation runs 32 MHz (twice the input signal analysis speed) +always @(posedge clk_out) begin + + // output counter synchronous to input and at twice the rate + sd_hcnt <= sd_hcnt + 10'd1; + if(hsD && !hs_in) sd_hcnt <= hs_max; + if(sd_hcnt == hs_max) sd_hcnt <= 10'd0; + + // replicate horizontal sync at twice the speed + if(sd_hcnt == hs_max) hs_sd <= 1'b0; + if(sd_hcnt == hs_rise) hs_sd <= 1'b1; + + // read data from line sd_buffer + sd_out <= sd_buffer[{~line_toggle, sd_hcnt}]; +end + +endmodule diff --git a/tutorials/soc/lesson12/soc.qpf b/tutorials/soc/lesson12/soc.qpf new file mode 100644 index 0000000..a057227 --- /dev/null +++ b/tutorials/soc/lesson12/soc.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2010 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 10.1 Build 153 11/29/2010 SJ Full Version +# Date created = 11:11:11 June 13, 2011 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "10.1" +DATE = "11:11:11 June 13, 2011" + +# Revisions + +PROJECT_REVISION = "soc" diff --git a/tutorials/soc/lesson12/soc.qsf b/tutorials/soc/lesson12/soc.qsf new file mode 100644 index 0000000..979792e --- /dev/null +++ b/tutorials/soc/lesson12/soc.qsf @@ -0,0 +1,165 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2011 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II +# Version 11.0 Build 157 04/27/2011 SJ Full Version +# Date created = 17:14:01 April 10, 2012 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# led_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + +set_global_assignment -name FAMILY "Cyclone III" +set_global_assignment -name DEVICE EP3C25E144C8 +set_global_assignment -name TOP_LEVEL_ENTITY soc +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 11.0 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "17:14:01 APRIL 10, 2012" +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name DEVICE_FILTER_PACKAGE "ANY QFP" +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 +set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "AS INPUT TRI-STATED" +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise +set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name GENERATE_RBF_FILE ON +set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" + +set_location_assignment PIN_7 -to LED +set_location_assignment PIN_22 -to CLOCK_50[0] +set_location_assignment PIN_23 -to CLOCK_50[1] +set_location_assignment PIN_128 -to CLOCK_32[0] +set_location_assignment PIN_129 -to CLOCK_32[1] +set_location_assignment PIN_54 -to CLOCK_27[0] +set_location_assignment PIN_55 -to CLOCK_27[1] +set_location_assignment PIN_144 -to VGA_R[5] +set_location_assignment PIN_143 -to VGA_R[4] +set_location_assignment PIN_142 -to VGA_R[3] +set_location_assignment PIN_141 -to VGA_R[2] +set_location_assignment PIN_137 -to VGA_R[1] +set_location_assignment PIN_135 -to VGA_R[0] +set_location_assignment PIN_133 -to VGA_B[5] +set_location_assignment PIN_132 -to VGA_B[4] +set_location_assignment PIN_125 -to VGA_B[3] +set_location_assignment PIN_121 -to VGA_B[2] +set_location_assignment PIN_120 -to VGA_B[1] +set_location_assignment PIN_115 -to VGA_B[0] +set_location_assignment PIN_114 -to VGA_G[5] +set_location_assignment PIN_113 -to VGA_G[4] +set_location_assignment PIN_112 -to VGA_G[3] +set_location_assignment PIN_111 -to VGA_G[2] +set_location_assignment PIN_110 -to VGA_G[1] +set_location_assignment PIN_106 -to VGA_G[0] +set_location_assignment PIN_136 -to VGA_VS +set_location_assignment PIN_119 -to VGA_HS +set_location_assignment PIN_65 -to AUDIO_L +set_location_assignment PIN_80 -to AUDIO_R +set_location_assignment PIN_46 -to UART_TX +set_location_assignment PIN_31 -to UART_RX +set_location_assignment PIN_105 -to SPI_DO +set_location_assignment PIN_88 -to SPI_DI +set_location_assignment PIN_126 -to SPI_SCK +set_location_assignment PIN_127 -to SPI_SS2 +set_location_assignment PIN_91 -to SPI_SS3 +set_location_assignment PIN_90 -to SPI_SS4 +set_location_assignment PIN_13 -to CONF_DATA0 + +set_location_assignment PIN_49 -to SDRAM_A[0] +set_location_assignment PIN_44 -to SDRAM_A[1] +set_location_assignment PIN_42 -to SDRAM_A[2] +set_location_assignment PIN_39 -to SDRAM_A[3] +set_location_assignment PIN_4 -to SDRAM_A[4] +set_location_assignment PIN_6 -to SDRAM_A[5] +set_location_assignment PIN_8 -to SDRAM_A[6] +set_location_assignment PIN_10 -to SDRAM_A[7] +set_location_assignment PIN_11 -to SDRAM_A[8] +set_location_assignment PIN_28 -to SDRAM_A[9] +set_location_assignment PIN_50 -to SDRAM_A[10] +set_location_assignment PIN_30 -to SDRAM_A[11] +set_location_assignment PIN_32 -to SDRAM_A[12] +set_location_assignment PIN_83 -to SDRAM_DQ[0] +set_location_assignment PIN_79 -to SDRAM_DQ[1] +set_location_assignment PIN_77 -to SDRAM_DQ[2] +set_location_assignment PIN_76 -to SDRAM_DQ[3] +set_location_assignment PIN_72 -to SDRAM_DQ[4] +set_location_assignment PIN_71 -to SDRAM_DQ[5] +set_location_assignment PIN_69 -to SDRAM_DQ[6] +set_location_assignment PIN_68 -to SDRAM_DQ[7] +set_location_assignment PIN_86 -to SDRAM_DQ[8] +set_location_assignment PIN_87 -to SDRAM_DQ[9] +set_location_assignment PIN_98 -to SDRAM_DQ[10] +set_location_assignment PIN_99 -to SDRAM_DQ[11] +set_location_assignment PIN_100 -to SDRAM_DQ[12] +set_location_assignment PIN_101 -to SDRAM_DQ[13] +set_location_assignment PIN_103 -to SDRAM_DQ[14] +set_location_assignment PIN_104 -to SDRAM_DQ[15] +set_location_assignment PIN_58 -to SDRAM_BA[0] +set_location_assignment PIN_51 -to SDRAM_BA[1] +set_location_assignment PIN_85 -to SDRAM_DQMH +set_location_assignment PIN_67 -to SDRAM_DQML +set_location_assignment PIN_60 -to SDRAM_nRAS +set_location_assignment PIN_64 -to SDRAM_nCAS +set_location_assignment PIN_66 -to SDRAM_nWE +set_location_assignment PIN_59 -to SDRAM_nCS +set_location_assignment PIN_33 -to SDRAM_CKE +set_location_assignment PIN_43 -to SDRAM_CLK + + +set_global_assignment -name ENABLE_SIGNALTAP OFF +set_global_assignment -name USE_SIGNALTAP_FILE stp1.stp +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON +set_global_assignment -name FITTER_EFFORT "FAST FIT" +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" +set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_* +set_global_assignment -name SYSTEMVERILOG_FILE rgb2ypbpr.sv +set_global_assignment -name VERILOG_FILE video.v +set_global_assignment -name VERILOG_FILE scandoubler.v +set_global_assignment -name VERILOG_FILE user_io.v +set_global_assignment -name VERILOG_FILE osd.v +set_global_assignment -name VERILOG_FILE soc.v +set_global_assignment -name QIP_FILE image.qip +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/tutorials/soc/lesson12/soc.rbf b/tutorials/soc/lesson12/soc.rbf new file mode 100644 index 0000000..076f041 Binary files /dev/null and b/tutorials/soc/lesson12/soc.rbf differ diff --git a/tutorials/soc/lesson12/soc.v b/tutorials/soc/lesson12/soc.v new file mode 100644 index 0000000..4e29e78 --- /dev/null +++ b/tutorials/soc/lesson12/soc.v @@ -0,0 +1,194 @@ +// A simple system-on-a-chip (SoC) for the MiST +// (c) 2015 Till Harbaum + +module soc ( + input [1:0] CLOCK_27, + output SDRAM_nCS, + + // SPI interface to arm io controller + output SPI_DO, + input SPI_DI, + input SPI_SCK, + input SPI_SS2, + input SPI_SS3, + input SPI_SS4, + input CONF_DATA0, + + output VGA_HS, + output VGA_VS, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B +); + +// de-activate unused SDRAM +assign SDRAM_nCS = 1; + +// the configuration string is returned to the io controller to allow +// it to control the menu on the OSD +parameter CONF_STR = { + "VID_TEST;;", + "O1,Scanlines,On,Off;", + "O2,Video Mode,NTSC,PAL" +}; + +wire scanlines_ena = !status[1]; +wire pal_ena = status[2]; + +parameter CONF_STR_LEN = 10+20+22; + +// the status register is controlled by the on screen display (OSD) +wire scandoubler_disable; +wire ypbpr; +wire [7:0] status; + +// include user_io module for arm controller communication +user_io #(.STRLEN(CONF_STR_LEN)) user_io ( + .conf_str ( CONF_STR ), + .SPI_CLK ( SPI_SCK ), + .SPI_SS_IO ( CONF_DATA0 ), + .SPI_MISO ( SPI_DO ), + .SPI_MOSI ( SPI_DI ), + .scandoubler_disable ( scandoubler_disable ), + .ypbpr ( ypbpr ), + .status ( status ) +); + +wire [5:0] video_r, video_g, video_b; +wire video_hs, video_vs; + +// include VGA controller +video video ( + .pclk ( pixel_clock ), + + .cpu_clk ( pixel_clock ), + .cpu_wr ( copy_in_progress ), + .cpu_addr ( addr - 14'd1 ), + .cpu_data ( data ), + .pal ( pal_ena ), + + .hs ( video_hs ), + .vs ( video_vs ), + .r ( video_r ), + .g ( video_g ), + .b ( video_b ) +); + +wire [5:0] sd_r, sd_g, sd_b; +wire sd_hs, sd_vs; + +scandoubler scandoubler ( + .clk_in ( pixel_clock ), + .clk_out ( vga_clock ), + .scanlines ( scanlines_ena ), + + // + .hs_in ( video_hs ), + .vs_in ( video_vs ), + .r_in ( video_r ), + .g_in ( video_g ), + .b_in ( video_b ), + + .hs_out ( sd_hs ), + .vs_out ( sd_vs ), + .r_out ( sd_r ), + .g_out ( sd_g ), + .b_out ( sd_b ) +); + +// In TV (15khz) mode the composite sync signal required by TVs is output on +// the VGA_HS output. The VGA_VS is driven to high and can be used e.g. to switch +// a scart tv into RGBS mode. See https://github.com/mist-devel/mist-board/wiki/ScartCable +assign VGA_HS = (scandoubler_disable || ypbpr)?!(video_hs^video_vs):sd_hs; +assign VGA_VS = (scandoubler_disable || ypbpr)?1'b1:sd_vs; +assign VGA_R = ypbpr?pr:out_r; +assign VGA_G = ypbpr? y:out_g; +assign VGA_B = ypbpr?pb:out_b; + +wire [5:0] y, pb, pr; + +// include the rgb to ypbpr colorspace converter +rgb2ypbpr rgb2ypbpr ( + .red ( out_r ), + .green ( out_g ), + .blue ( out_b ), + + .y ( y ), + .pb ( pb ), + .pr ( pr ) +); + +wire [5:0] out_r, out_g, out_b; + +// Make sure OSD scales horizontally to double size on TV as it also scales +// vertically since the scandoubler is disabled and thus only half the number of lines +// is being displayed making every line twice as high +wire osd_clk = scandoubler_disable?pixel_clock:vga_clock; + +// Feed scnadoubled or normal signal into OSD +wire osd_hs = scandoubler_disable?video_hs:sd_hs; +wire osd_vs = scandoubler_disable?video_vs:sd_vs; +wire [5:0] osd_r = scandoubler_disable?video_r:sd_r; +wire [5:0] osd_g = scandoubler_disable?video_g:sd_g; +wire [5:0] osd_b = scandoubler_disable?video_b:sd_b; + +// include the on screen display +osd #(10,0,4) osd ( + .pclk ( osd_clk ), + + // spi for OSD + .sdi ( SPI_DI ), + .sck ( SPI_SCK ), + .ss ( SPI_SS3 ), + + .red_in ( osd_r ), + .green_in ( osd_g ), + .blue_in ( osd_b ), + .hs_in ( osd_hs ), + .vs_in ( osd_vs ), + + .red_out ( out_r ), + .green_out ( out_g ), + .blue_out ( out_b ) +); + +// include ROM containing the demo image +image image ( + .clock ( pixel_clock ), + .address ( addr ), + .q ( data ) +); + +reg reset = 1'b1; +reg [13:0] addr; +wire [7:0] data; +reg copy_in_progress; + +// A small state machine which copies image data from ROM into VRAM +// of the video controller. The state machines runs directly after power +// on and works on the falling clock edge since ROM and VRAM operate +// in the rising edge. The VRAM address is dereased by 1 since the ROM +// delivers it's data with one clock delay due to its internal registers. +always @(negedge pixel_clock) begin + if(reset) begin + reset <= 1'b0; + addr <= 14'd0; + copy_in_progress <= 1'b1; + end else begin + if(copy_in_progress) begin + addr <= addr + 14'd1; + if(addr == 15999) + copy_in_progress <= 1'b0; + end + end +end + +reg pixel_clock; +always @(posedge vga_clock) + pixel_clock <= !pixel_clock; + +// The pixel clock we use for our TV video modes is 13.5 Mhz. Thus the VGA pixel +// clock is exactly the 27 Mhz MIST board clock. No pll needed ... +wire vga_clock = CLOCK_27[0]; + +endmodule diff --git a/tutorials/soc/lesson12/user_io.v b/tutorials/soc/lesson12/user_io.v new file mode 100644 index 0000000..5cecc55 --- /dev/null +++ b/tutorials/soc/lesson12/user_io.v @@ -0,0 +1,417 @@ +// +// user_io.v +// +// user_io for the MiST board +// http://code.google.com/p/mist-board/ +// +// Copyright (c) 2014 Till Harbaum +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +// parameter STRLEN and the actual length of conf_str have to match + +module user_io #(parameter STRLEN=0) ( + input [(8*STRLEN)-1:0] conf_str, + + input SPI_CLK, + input SPI_SS_IO, + output reg SPI_MISO, + input SPI_MOSI, + + output reg [7:0] joystick_0, + output reg [7:0] joystick_1, + output reg [15:0] joystick_analog_0, + output reg [15:0] joystick_analog_1, + output [1:0] buttons, + output [1:0] switches, + output scandoubler_disable, + output ypbpr, + + output reg [7:0] status, + + // connection to sd card emulation + input [31:0] sd_lba, + input sd_rd, + input sd_wr, + output reg sd_ack, + input sd_conf, + input sd_sdhc, + output [7:0] sd_dout, // valid on rising edge of sd_dout_strobe + output reg sd_dout_strobe, + input [7:0] sd_din, + output reg sd_din_strobe, + + + // ps2 keyboard emulation + input ps2_clk, // 12-16khz provided by core + output ps2_kbd_clk, + output reg ps2_kbd_data, + output ps2_mouse_clk, + output reg ps2_mouse_data, + + // serial com port + input [7:0] serial_data, + input serial_strobe +); + +reg [6:0] sbuf; +reg [7:0] cmd; +reg [2:0] bit_cnt; // counts bits 0-7 0-7 ... +reg [7:0] byte_cnt; // counts bytes +reg [5:0] joystick0; +reg [5:0] joystick1; +reg [5:0] but_sw; +reg [2:0] stick_idx; + +assign buttons = but_sw[1:0]; +assign switches = but_sw[3:2]; +assign scandoubler_disable = but_sw[4]; +assign ypbpr = but_sw[5]; + +assign sd_dout = { sbuf, SPI_MOSI}; + +// this variant of user_io is for 8 bit cores (type == a4) only +wire [7:0] core_type = 8'ha4; + +// command byte read by the io controller +wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd }; + +// filter spi clock. the 8 bit gate delay is ~2.5ns in total +wire [7:0] spi_sck_D = { spi_sck_D[6:0], SPI_CLK } /* synthesis keep */; +wire spi_sck = (spi_sck && spi_sck_D != 8'h00) || (!spi_sck && spi_sck_D == 8'hff); + +// drive MISO only when transmitting core id +always@(negedge spi_sck or posedge SPI_SS_IO) begin + if(SPI_SS_IO == 1) begin + SPI_MISO <= 1'bZ; + end else begin + + // first byte returned is always core type, further bytes are + // command dependent + if(byte_cnt == 0) begin + SPI_MISO <= core_type[~bit_cnt]; + + end else begin + // reading serial fifo + if(cmd == 8'h1b) begin + // send alternating flag byte and data + if(byte_cnt[0]) SPI_MISO <= serial_out_status[~bit_cnt]; + else SPI_MISO <= serial_out_byte[~bit_cnt]; + end + + // reading config string + else if(cmd == 8'h14) begin + // returning a byte from string + if(byte_cnt < STRLEN + 1) + SPI_MISO <= conf_str[{STRLEN - byte_cnt,~bit_cnt}]; + else + SPI_MISO <= 1'b0; + end + + // reading sd card status + else if(cmd == 8'h16) begin + if(byte_cnt == 1) + SPI_MISO <= sd_cmd[~bit_cnt]; + else if((byte_cnt >= 2) && (byte_cnt < 6)) + SPI_MISO <= sd_lba[{5-byte_cnt, ~bit_cnt}]; + else + SPI_MISO <= 1'b0; + end + + // reading sd card write data + else if(cmd == 8'h18) + SPI_MISO <= sd_din[~bit_cnt]; + + else + SPI_MISO <= 1'b0; + end + end +end + +// ---------------- PS2 --------------------- + +// 8 byte fifos to store ps2 bytes +localparam PS2_FIFO_BITS = 3; + +// keyboard +reg [7:0] ps2_kbd_fifo [(2**PS2_FIFO_BITS)-1:0]; +reg [PS2_FIFO_BITS-1:0] ps2_kbd_wptr; +reg [PS2_FIFO_BITS-1:0] ps2_kbd_rptr; + +// ps2 transmitter state machine +reg [3:0] ps2_kbd_tx_state; +reg [7:0] ps2_kbd_tx_byte; +reg ps2_kbd_parity; + +assign ps2_kbd_clk = ps2_clk || (ps2_kbd_tx_state == 0); + +// ps2 transmitter +// Takes a byte from the FIFO and sends it in a ps2 compliant serial format. +reg ps2_kbd_r_inc; +always@(posedge ps2_clk) begin + ps2_kbd_r_inc <= 1'b0; + + if(ps2_kbd_r_inc) + ps2_kbd_rptr <= ps2_kbd_rptr + 1; + + // transmitter is idle? + if(ps2_kbd_tx_state == 0) begin + // data in fifo present? + if(ps2_kbd_wptr != ps2_kbd_rptr) begin + // load tx register from fifo + ps2_kbd_tx_byte <= ps2_kbd_fifo[ps2_kbd_rptr]; + ps2_kbd_r_inc <= 1'b1; + + // reset parity + ps2_kbd_parity <= 1'b1; + + // start transmitter + ps2_kbd_tx_state <= 4'd1; + + // put start bit on data line + ps2_kbd_data <= 1'b0; // start bit is 0 + end + end else begin + + // transmission of 8 data bits + if((ps2_kbd_tx_state >= 1)&&(ps2_kbd_tx_state < 9)) begin + ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits + ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down + if(ps2_kbd_tx_byte[0]) + ps2_kbd_parity <= !ps2_kbd_parity; + end + + // transmission of parity + if(ps2_kbd_tx_state == 9) + ps2_kbd_data <= ps2_kbd_parity; + + // transmission of stop bit + if(ps2_kbd_tx_state == 10) + ps2_kbd_data <= 1'b1; // stop bit is 1 + + // advance state machine + if(ps2_kbd_tx_state < 11) + ps2_kbd_tx_state <= ps2_kbd_tx_state + 4'd1; + else + ps2_kbd_tx_state <= 4'd0; + + end +end + +// mouse +reg [7:0] ps2_mouse_fifo [(2**PS2_FIFO_BITS)-1:0]; +reg [PS2_FIFO_BITS-1:0] ps2_mouse_wptr; +reg [PS2_FIFO_BITS-1:0] ps2_mouse_rptr; + +// ps2 transmitter state machine +reg [3:0] ps2_mouse_tx_state; +reg [7:0] ps2_mouse_tx_byte; +reg ps2_mouse_parity; + +assign ps2_mouse_clk = ps2_clk || (ps2_mouse_tx_state == 0); + +// ps2 transmitter +// Takes a byte from the FIFO and sends it in a ps2 compliant serial format. +reg ps2_mouse_r_inc; +always@(posedge ps2_clk) begin + ps2_mouse_r_inc <= 1'b0; + + if(ps2_mouse_r_inc) + ps2_mouse_rptr <= ps2_mouse_rptr + 1; + + // transmitter is idle? + if(ps2_mouse_tx_state == 0) begin + // data in fifo present? + if(ps2_mouse_wptr != ps2_mouse_rptr) begin + // load tx register from fifo + ps2_mouse_tx_byte <= ps2_mouse_fifo[ps2_mouse_rptr]; + ps2_mouse_r_inc <= 1'b1; + + // reset parity + ps2_mouse_parity <= 1'b1; + + // start transmitter + ps2_mouse_tx_state <= 4'd1; + + // put start bit on data line + ps2_mouse_data <= 1'b0; // start bit is 0 + end + end else begin + + // transmission of 8 data bits + if((ps2_mouse_tx_state >= 1)&&(ps2_mouse_tx_state < 9)) begin + ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits + ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down + if(ps2_mouse_tx_byte[0]) + ps2_mouse_parity <= !ps2_mouse_parity; + end + + // transmission of parity + if(ps2_mouse_tx_state == 9) + ps2_mouse_data <= ps2_mouse_parity; + + // transmission of stop bit + if(ps2_mouse_tx_state == 10) + ps2_mouse_data <= 1'b1; // stop bit is 1 + + // advance state machine + if(ps2_mouse_tx_state < 11) + ps2_mouse_tx_state <= ps2_mouse_tx_state + 4'd1; + else + ps2_mouse_tx_state <= 4'd0; + + end +end + +// fifo to receive serial data from core to be forwarded to io controller + +// 16 byte fifo to store serial bytes +localparam SERIAL_OUT_FIFO_BITS = 6; +reg [7:0] serial_out_fifo [(2**SERIAL_OUT_FIFO_BITS)-1:0]; +reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_wptr; +reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_rptr; + +wire serial_out_data_available = serial_out_wptr != serial_out_rptr; +wire [7:0] serial_out_byte = serial_out_fifo[serial_out_rptr] /* synthesis keep */; +wire [7:0] serial_out_status = { 7'b1000000, serial_out_data_available}; + +// status[0] is reset signal from io controller and is thus used to flush +// the fifo +always @(posedge serial_strobe or posedge status[0]) begin + if(status[0] == 1) begin + serial_out_wptr <= 0; + end else begin + serial_out_fifo[serial_out_wptr] <= serial_data; + serial_out_wptr <= serial_out_wptr + 1; + end +end + +always@(negedge spi_sck or posedge status[0]) begin + if(status[0] == 1) begin + serial_out_rptr <= 0; + end else begin + if((byte_cnt != 0) && (cmd == 8'h1b)) begin + // read last bit -> advance read pointer + if((bit_cnt == 7) && !byte_cnt[0] && serial_out_data_available) + serial_out_rptr <= serial_out_rptr + 1; + end + end +end + +// SPI receiver +always@(posedge spi_sck or posedge SPI_SS_IO) begin + + if(SPI_SS_IO == 1) begin + bit_cnt <= 3'd0; + byte_cnt <= 8'd0; + sd_ack <= 1'b0; + sd_dout_strobe <= 1'b0; + sd_din_strobe <= 1'b0; + end else begin + sd_dout_strobe <= 1'b0; + sd_din_strobe <= 1'b0; + + if(bit_cnt != 7) + sbuf[6:0] <= { sbuf[5:0], SPI_MOSI }; + + bit_cnt <= bit_cnt + 3'd1; + if((bit_cnt == 7)&&(byte_cnt != 8'd255)) + byte_cnt <= byte_cnt + 8'd1; + + // finished reading command byte + if(bit_cnt == 7) begin + if(byte_cnt == 0) begin + cmd <= { sbuf, SPI_MOSI}; + + // fetch first byte when sectore FPGA->IO command has been seen + if({ sbuf, SPI_MOSI} == 8'h18) + sd_din_strobe <= 1'b1; + + if(({ sbuf, SPI_MOSI} == 8'h17) || ({ sbuf, SPI_MOSI} == 8'h18)) + sd_ack <= 1'b1; + + end else begin + + // buttons and switches + if(cmd == 8'h01) + but_sw <= { sbuf[4:0], SPI_MOSI }; + + if(cmd == 8'h02) + joystick_0 <= { sbuf, SPI_MOSI }; + + if(cmd == 8'h03) + joystick_1 <= { sbuf, SPI_MOSI }; + + if(cmd == 8'h04) begin + // store incoming ps2 mouse bytes + ps2_mouse_fifo[ps2_mouse_wptr] <= { sbuf, SPI_MOSI }; + ps2_mouse_wptr <= ps2_mouse_wptr + 1; + end + + if(cmd == 8'h05) begin + // store incoming ps2 keyboard bytes + ps2_kbd_fifo[ps2_kbd_wptr] <= { sbuf, SPI_MOSI }; + ps2_kbd_wptr <= ps2_kbd_wptr + 1; + end + + if(cmd == 8'h15) + status <= { sbuf[6:0], SPI_MOSI }; + + // send sector IO -> FPGA + if(cmd == 8'h17) begin + // flag that download begins +// sd_dout <= { sbuf, SPI_MOSI}; + sd_dout_strobe <= 1'b1; + end + + // send sector FPGA -> IO + if(cmd == 8'h18) + sd_din_strobe <= 1'b1; + + // send SD config IO -> FPGA + if(cmd == 8'h19) begin + // flag that download begins +// sd_dout <= { sbuf, SPI_MOSI}; + // sd card knows data is config if sd_dout_strobe is asserted + // with sd_ack still being inactive (low) + sd_dout_strobe <= 1'b1; + end + + // joystick analog + if(cmd == 8'h1a) begin + // first byte is joystick indes + if(byte_cnt == 1) + stick_idx <= { sbuf[1:0], SPI_MOSI }; + else if(byte_cnt == 2) begin + // second byte is x axis + if(stick_idx == 0) + joystick_analog_0[15:8] <= { sbuf, SPI_MOSI }; + else if(stick_idx == 1) + joystick_analog_1[15:8] <= { sbuf, SPI_MOSI }; + end else if(byte_cnt == 3) begin + // third byte is y axis + if(stick_idx == 0) + joystick_analog_0[7:0] <= { sbuf, SPI_MOSI }; + else if(stick_idx == 1) + joystick_analog_1[7:0] <= { sbuf, SPI_MOSI }; + end + end + + end + end + end +end + +endmodule diff --git a/tutorials/soc/lesson12/video.v b/tutorials/soc/lesson12/video.v new file mode 100644 index 0000000..c18a0a5 --- /dev/null +++ b/tutorials/soc/lesson12/video.v @@ -0,0 +1,124 @@ +// A simple system-on-a-chip (SoC) for the MiST +// (c) 2016 Till Harbaum + +// video controller generating 160x100 pixles. The video mode is based +// upon a non-interlaced PAL or NTSC TV mode. + + +module video ( + // pixel clock + input pclk, + + // config input + input pal, + + // CPU interface (write only!) + input cpu_clk, + input cpu_wr, + input [13:0] cpu_addr, + input [7:0] cpu_data, + + // output to VGA screen + output reg hs, + output reg vs, + output [5:0] r, + output [5:0] g, + output [5:0] b +); + +// PAL timing: +// 864 pixel total horizontal @ 13.5 Mhz = 15.625 kHz +// 312 lines vertically @ 15.625 kHz = 50.08 Hz + +// NTSC timing: +// 858 pixel total horizontal @ 13.5 Mhz = 15.735 kHz +// 262 lines vertically @ 15.735 kHz = 60.05 Hz + +parameter H = 640; // width of visible area +wire [9:0] hfp = pal?51:56; // unused time before hsync +wire [9:0] hsw = pal?63:63; // width of hsync +wire [9:0] hbp = pal?110:99; // unused time after hsync + +parameter V = 200; // height of visible area +wire [9:0] vfp = pal?46:23; // unused time before vsync +wire [9:0] vsw = pal?2:3; // width of vsync +wire [9:0] vbp = pal?64:36; // unused time after vsync + +reg[9:0] h_cnt; // horizontal pixel counter +reg[9:0] v_cnt; // vertical pixel counter + +// horizontal pixel counter +always@(posedge pclk) begin + if(h_cnt==H+hfp+hsw+hbp-1) h_cnt <= 10'd0; + else h_cnt <= h_cnt + 10'd1; + + // generate negative hsync signal + if(h_cnt == H+hfp) hs <= 1'b0; + if(h_cnt == H+hfp+hsw) hs <= 1'b1; +end + +// veritical pixel counter +always@(posedge pclk) begin + // the vertical counter is processed at the begin of each hsync + if(h_cnt == H+hfp) begin + if(v_cnt==vsw+vbp+V+vfp-1) v_cnt <= 10'd0; + else v_cnt <= v_cnt + 10'd1; + + // generate negative vsync signal + if(v_cnt == V+vfp) vs <= 1'b0; + if(v_cnt == V+vfp+vsw) vs <= 1'b1; + end +end + +// 16000 bytes of internal video memory for 160x100 pixel at 8 Bit (RGB 332) +reg [7:0] vmem [160*100-1:0]; + +reg [13:0] video_counter; +reg [7:0] pixel; + +// write VRAM via CPU interface +always @(posedge cpu_clk) + if(cpu_wr) + vmem[cpu_addr] <= cpu_data; + +// read VRAM for video generation +always@(posedge pclk) begin + // The video counter is being reset at the begin of each vsync. + // Otherwise it's increased every fourth pixel in the visible area. + // At the end of the first three of four lines the counter is + // decreased by the total line length to display the same contents + // for four lines so 100 different lines are displayed on the 400 + // VGA lines. + + // visible area? + if((v_cnt < V) && (h_cnt < H)) begin + // increase video counter after each pixel + if(h_cnt[1:0] == 2'd3) + video_counter <= video_counter + 14'd1; + + pixel <= vmem[video_counter]; // read VRAM + end else begin + // video counter is manipulated at the end of a line outside + // the visible area + if(h_cnt == H+hfp) begin + // the video counter is reset at the begin of the vsync + // at the end of every second line it's decremented + // one line to repeat the same pixels over two display + // lines + if(v_cnt == V+vfp) + video_counter <= 14'd0; + else if((v_cnt < V) && (v_cnt[0] != 2'd1)) + video_counter <= video_counter - 14'd160; + end + + pixel <= 8'h00; // color outside visible area: black + end +end + +// split the 8 rgb bits into the three base colors. Every second line is +// darker to give some scanlines effect +assign r = { pixel[7:5], 3'b000 }; +assign g = { pixel[4:2], 3'b000 }; +assign b = { pixel[1:0], 4'b0000 }; + +endmodule diff --git a/tutorials/soc/readme.md b/tutorials/soc/readme.md index 97a84e7..cbe8ecd 100644 --- a/tutorials/soc/readme.md +++ b/tutorials/soc/readme.md @@ -721,4 +721,38 @@ Links: Files required on SD card: - [`soc.rbf`](https://github.com/mist-devel/mist-board/raw/master/tutorials/soc/lesson11/soc.rbf) renamed to `core.rbf` + +[Lesson 12](https://github.com/mist-devel/mist-board/tree/master/tutorials/soc/lesson12): YPbPr component video +------------------------------- + +SCART is a nice way to send a true "retro" video signal to a TV. +Unfortunately SCART or any other kind of RGBs input isn't available +on most modern TVs anymore. + +What many TVs still have is a so-called YPbPr component input. This +type of input uses three connections Y, Pb and Pr. Y carries a +geyscale signal together with a composite sync signal. Thus only +connecting the Y signal may already result in a grayscale image +on many TVs. The other two signal Pb and Pr carry color difference +signals. Together with the Y signal they allow the TV to reconstruct +the color. + +For YPbPr a special adaptor is need for the MIST as described in the +[MIST wiki](https://github.com/mist-devel/mist-board/wiki/YPbPr_Cable). + +Many TVs support various common video modes on their component inputs. +It is thus often possible to use the YPbPr with or without +scandoubler. With scandoubler enabled the resulting 720p modes may +even use scanline effects. + +This makes a YPbPr connection a very nice choice when connecting the +MIST to many modern TVs. + +Links: + - [MIST YpbPr adapter](https://github.com/mist-devel/mist-board/wiki/YPbPr_Cable) + - [Enabling YPbPr in the MIST .ini file](https://github.com/mist-devel/mist-board/wiki/DocIni#ypbpr) + - [Buy a cable](http://lotharek.pl/product.php?pid=168) + +Files required on SD card: + - [`soc.rbf`](https://github.com/mist-devel/mist-board/raw/master/tutorials/soc/lesson12/soc.rbf) renamed to `core.rbf` \ No newline at end of file