{"id":1045,"date":"2025-10-05T20:31:46","date_gmt":"2025-10-05T12:31:46","guid":{"rendered":"https:\/\/vm1.go2see.me\/?p=1045"},"modified":"2025-10-05T22:28:52","modified_gmt":"2025-10-05T14:28:52","slug":"lab-5-combination-lock-part-1","status":"publish","type":"post","link":"https:\/\/vm1.go2see.me\/?p=1045","title":{"rendered":"Lab 5: Combination Lock Part 1"},"content":{"rendered":"<h1>Lab 5: Combination Lock Part 1<\/h1>\n<blockquote>\n<p>Modified from Digital Design and Computer Architecture: RISC-V Edition (Harris &amp; Harris, Elsevier \u00a9 2021)<\/p>\n<\/blockquote>\n<h2>Objective<\/h2>\n<p>The purpose of this lab is learn to design a small Moore FSM and accompanying combinational logic  circuit. You will use both manual gate-level design and behavioural SystemVerilog design with Quartus.  <\/p>\n<p>In this lab you will design a circuit that locks and unlocks a safe that you might find in a hotel room. <\/p>\n<p>To  use the safe, you place an item inside, close the door and enter any combination as a 10-bit password to  lock the safe. To retrieve your item, you enter the same password again to unlock the safe. The process  can be repeated as often as desired, each time using any combination you want. <\/p>\n<h3>1. Overall Operation<\/h3>\n<ul>\n<li>\n<p>Inputs:   <\/p>\n<p>CLK50: automatically generated 50MHz clock<\/p>\n<p>SW[9:0]: 10-bit user-entered numeric value<\/p>\n<p>KEY[0]: synchronous RESET<\/p>\n<p>KEY[1] : ENTER <\/p>\n<\/li>\n<li>\n<p>Outputs:  <\/p>\n<p>HEX5 to HEX0\uff1a user interface, displays <code>LOCHED<\/code> or <code>_OPEn_<\/code><\/p>\n<p>LEDR[9] : <code>MATCH<\/code> displays (<code>ATTEMPT==PASSWORD<\/code>)  <\/p>\n<p>LEDR[8]: <code>PREMATCH<\/code> displays (<code>SW==PASSWORD<\/code>) <\/p>\n<p>LEDR[3:0]: <code>COUNT=count_ones<\/code>(<code>ATTEMPT XOR PASSWORD<\/code>) <\/p>\n<\/li>\n<li>\n<p>State Bits:  <\/p>\n<p>PASSWORD: 10-bit user-entered password to unlock the safe<\/p>\n<p>ATTEMPT: 10-bit user-entered attempt to unlock the safe <\/p>\n<p>CURRENT_STATE: as many bits as required for FSM<\/p>\n<\/li>\n<\/ul>\n<p>Operation: <\/p>\n<ul>\n<li>50MHz clock drives all flip-flops in CURRENT_STATE, PASSWORD and ATTEMPT<\/li>\n<li>Synchronous reset occurs when RESET is low:\n<ul>\n<li>CURRENT_STATE changes to the OPEN state<\/li>\n<li>ATTEMPT is set to all 1s<\/li>\n<li>PASSWORD is cleared to all 0s<\/li>\n<\/ul>\n<\/li>\n<li>The FSM has <code>two primary states<\/code>, LOCKED and OPEN\n<ul>\n<li>User must press and release <strong>ENTER<\/strong> to switch to the other primary state<\/li>\n<li><code>LOCKED<\/code>: displays LOCHED and stores SW as ATTEMPT when <strong>ENTER<\/strong> pressed  <\/li>\n<li><code>OPEN<\/code>: displays <code>_OPEn_ <\/code>and stores SW as PASSWORD when <strong>ENTER<\/strong> pressed<\/li>\n<li><code>OPEN<\/code> &#8211;&gt;  <code>LOCKED<\/code> transitions when <strong>ENTER<\/strong> is pressed<\/li>\n<li><code>LOCKED<\/code> &#8211;&gt; <code>OPEN<\/code> transitions when <strong>ENTER<\/strong> is pressed and <code>MATCH<\/code><\/li>\n<\/ul>\n<\/li>\n<li>The FSM has <strong>additional states<\/strong> (as many as required)\n<ul>\n<li>The role of these states is to wait for the user to release <strong>ENTER<\/strong><\/li>\n<li>Without these, the FSM races between the two primary states while <strong>ENTER<\/strong> is pressed<\/li>\n<\/ul>\n<\/li>\n<li>Diagnostic display (for testing and safe cracking)\n<ul>\n<li>LEDR[9] displays MATCH to indicate when ATTEMPT == PASSWORD<\/li>\n<li>LEDR[8] displays PREMATCH to indicate when SW == PASSWORD<\/li>\n<li>LEDR[3:0] displays COUNT, the number of incorrect ATTEMPT bits<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>2. Combinational Logic<\/h3>\n<p>Write one always_comb block to: <\/p>\n<ul>\n<li>Compute MATCH, PREMATCH, and COUNT\n<ul>\n<li>Use inputs SW, ATTEMPT and PASSWORD<\/li>\n<\/ul>\n<\/li>\n<li>Connect these to LEDR<\/li>\n<\/ul>\n<h3>3. Registers<\/h3>\n<p>Using the CLK50, RESET and other signals noted below, write one always_ff block to: <\/p>\n<ul>\n<li>Update PASSWORD register\n<ul>\n<li>When logic signal <strong>savePW<\/strong> is set, save the value of SW to PASSWORD<\/li>\n<\/ul>\n<\/li>\n<li>Update ATTEMPT register\n<ul>\n<li>When logic signal <strong>saveAT<\/strong> is set, save the value of SW to ATTEMPT<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>4. Manual FSM Design<\/h3>\n<p>On paper, using the Moore Machine FSM model, follow the FSM design process: <\/p>\n<ul>\n<li>Determine what FSM inputs are required <\/li>\n<li>Determine what FSM outputs are required <\/li>\n<li>Draw the State Diagram needed to control the safe <\/li>\n<li>Convert the State Diagram to a State Table that clearly shows the next states and all outputs <\/li>\n<li>Write down your desired State Encoding  <\/li>\n<li>Convert the State Table to a State Table with State Encodings <\/li>\n<li>Convert the State Table with State Encodings into Karnaugh maps <\/li>\n<li>From the Karnaugh Map, determine the sum-of-product logic equations for\n<ul>\n<li>All next-state bits <\/li>\n<li>All output bits<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>Create a SystemVerilog module for the FSM including all necessary inputs and outputs. Don\u2019t forget the clock and reset signals! <\/p>\n<pre><code class=\"language-verilog\">module fsm_gates( \n    input logic xxx,\n    \/\/ etc \n    output logic zzz\uff0c\n    \/\/ etc \n); <\/code><\/pre>\n<h3>5. Putting it All Together, Part One<\/h3>\n<p>Create a new Quartus project and top-level module the following declaration:<\/p>\n<pre><code class=\"language-verilog\">module safe(\n    input logic. CLK50, \n    input logic  [1:0] KEY, \n    input logic  [9:0] SW, \n    output logic [9:0] LEDR, \n    output logic [7:0] HEX5, \n    output logic [7:0] HEX4, \n    output logic [7:0] HEX3, \n    output logic [7:0] HEX2, \n    output logic [7:0] HEX1, \n    output logic [7:0] HEX0 \n);<\/code><\/pre>\n<p>Inside the safe module, create an instance of your fsm module.<br \/>\nNormally, you would write a testbench for each module to fully test it out. <\/p>\n<p>However, testing sequential logic can be challenging. However, for expedience, we will forgot writing a testbench for this lab.<br \/>\nInstead, compile your project in Quartus, program your FPGA board, and test it. <\/p>\n<h4>Debugging:<\/h4>\n<p>At this stage, it is extremely unlikely you will get it to work \u2013 don\u2019t let that discourage you.<br \/>\nCheck over your work, especially the manual design process of the FSM. If you notice any errors, correct your logic equations and update your SystemVerilog code.<\/p>\n<h3>6. Putting it All Together, Part Two<\/h3>\n<p>In this section, instead of manually creating the FSM logic, write a SystemVerilog module named <strong>fsm_verilog<\/strong> that follows directly from the State Diagram or the State Table. Use as many always_ff and\/or always_comb blocks as you need.<br \/>\nIn your top-level safe module, replace the fsm_gates module with fsm_verilog. Compile the project, program the board, and test it. <\/p>\n<h4>Debugging:<\/h4>\n<p>An FSM written this way is much easier to debug and alter. It is also more descriptive, making it easier to get your FSM to work. Instead of worrying about state assignment and extracting correct logic equations from the Karnaugh maps, you can focus on describing the correct state transitions. <\/p>\n<h3>7. What to Turn In and Demonstrate<\/h3>\n<p>TBD.<\/p>\n<hr \/>\n<h2>Step-by-Step Strategy<\/h2>\n<h3>1. Combinational Logic Block<\/h3>\n<p>Create an <code>always_comb<\/code> block to compute:<\/p>\n<p>verilog<\/p>\n<pre><code>always_comb begin\n    MATCH    = (ATTEMPT == PASSWORD);\n    PREMATCH = (SW == PASSWORD);\n    COUNT    = 0;\n    for (int i = 0; i &lt; 10; i++)\n        COUNT += ATTEMPT[i] ^ PASSWORD[i];\n\n    LEDR[9]   = MATCH;\n    LEDR[8]   = PREMATCH;\n    LEDR[3:0] = COUNT;\nend<\/code><\/pre>\n<h3>2. Register Update Block<\/h3>\n<p>Use <code>always_ff<\/code> for synchronous updates:<\/p>\n<p>verilog<\/p>\n<pre><code>always_ff @(posedge CLK50) begin\n    if (!RESET) begin\n        PASSWORD &lt;= 10&#039;b0000000000;\n        ATTEMPT &lt;= 10&#039;b1111111111;\n    end else begin\n        if (savePW)\n            PASSWORD &lt;= SW;\n        if (saveAT)\n            ATTEMPT &lt;= SW;\n    end\nend<\/code><\/pre>\n<h3>3. Manual FSM Design<\/h3>\n<h4>Inputs:<\/h4>\n<ul>\n<li><code>ENTER<\/code>, <code>RESET<\/code>, <code>MATCH<\/code><\/li>\n<\/ul>\n<h4>Outputs:<\/h4>\n<ul>\n<li><code>savePW<\/code>, <code>saveAT<\/code>, <code>display_state<\/code><\/li>\n<\/ul>\n<h4>States:<\/h4>\n<ul>\n<li><code>OPEN<\/code>, <code>WAIT_OPEN_RELEASE<\/code>, <code>LOCKED<\/code>, <code>WAIT_LOCK_RELEASE<\/code>, <code>CHECK_MATCH<\/code><\/li>\n<\/ul>\n<h4>State Diagram:<\/h4>\n<ul>\n<li><code>OPEN<\/code> \u2192 (ENTER) \u2192 <code>WAIT_OPEN_RELEASE<\/code> \u2192 (ENTER released) \u2192 <code>LOCKED<\/code><\/li>\n<li><code>LOCKED<\/code> \u2192 (ENTER) \u2192 <code>CHECK_MATCH<\/code> \u2192 (MATCH) \u2192 <code>WAIT_LOCK_RELEASE<\/code> \u2192 (ENTER released) \u2192 <code>OPEN<\/code><\/li>\n<li>If no MATCH, stay in <code>LOCKED<\/code><\/li>\n<\/ul>\n<h4>Encoding Example:<\/h4>\n<p>verilog<\/p>\n<pre><code>typedef enum logic [2:0] {\n    OPEN              = 3&#039;b000,\n    WAIT_OPEN_RELEASE = 3&#039;b001,\n    LOCKED            = 3&#039;b010,\n    CHECK_MATCH       = 3&#039;b011,\n    WAIT_LOCK_RELEASE = 3&#039;b100\n} state_t;<\/code><\/pre>\n<h4>FSM Logic (fsm_verilog):<\/h4>\n<p>verilog<\/p>\n<pre><code>module fsm_verilog(\n    input  logic CLK50, RESET, ENTER, MATCH,\n    output logic savePW, saveAT,\n    output state_t CURRENT_STATE\n);\n    state_t state, next;\n\n    always_ff @(posedge CLK50 or negedge RESET) begin\n        if (!RESET)\n            state &lt;= OPEN;\n        else\n            state &lt;= next;\n    end\n\n    always_comb begin\n        savePW = 0;\n        saveAT = 0;\n        case (state)\n            OPEN: begin\n                if (ENTER) next = WAIT_OPEN_RELEASE;\n                else       next = OPEN;\n                savePW = ENTER;\n            end\n            WAIT_OPEN_RELEASE: begin\n                if (!ENTER) next = LOCKED;\n                else        next = WAIT_OPEN_RELEASE;\n            end\n            LOCKED: begin\n                if (ENTER) next = CHECK_MATCH;\n                else       next = LOCKED;\n                saveAT = ENTER;\n            end\n            CHECK_MATCH: begin\n                if (MATCH) next = WAIT_LOCK_RELEASE;\n                else       next = LOCKED;\n            end\n            WAIT_LOCK_RELEASE: begin\n                if (!ENTER) next = OPEN;\n                else        next = WAIT_LOCK_RELEASE;\n            end\n            default: next = OPEN;\n        endcase\n    end\nendmodule<\/code><\/pre>\n<h2>4. Top-Level Integration<\/h2>\n<p>verilog<\/p>\n<pre><code>module safe(\n    input  logic CLK50,\n    input  logic [1:0] KEY,\n    input  logic [9:0] SW,\n    output logic [9:0] LEDR,\n    output logic [7:0] HEX5, HEX4, HEX3, HEX2, HEX1, HEX0\n);\n    logic [9:0] PASSWORD, ATTEMPT;\n    logic MATCH, PREMATCH;\n    logic [3:0] COUNT;\n    logic savePW, saveAT;\n\n    \/\/ Instantiate FSM\n    fsm_verilog fsm_inst(\n        .CLK50(CLK50),\n        .RESET(KEY[0]),\n        .ENTER(KEY[1]),\n        .MATCH(MATCH),\n        .savePW(savePW),\n        .saveAT(saveAT)\n    );\n\n    \/\/ Combinational logic\n    always_comb begin\n        MATCH    = (ATTEMPT == PASSWORD);\n        PREMATCH = (SW == PASSWORD);\n        COUNT    = 0;\n        for (int i = 0; i &lt; 10; i++)\n            COUNT += ATTEMPT[i] ^ PASSWORD[i];\n\n        LEDR[9]   = MATCH;\n        LEDR[8]   = PREMATCH;\n        LEDR[3:0] = COUNT;\n    end\n\n    \/\/ Register logic\n    always_ff @(posedge CLK50) begin\n        if (!KEY[0]) begin\n            PASSWORD &lt;= 10&#039;b0000000000;\n            ATTEMPT &lt;= 10&#039;b1111111111;\n        end else begin\n            if (savePW) PASSWORD &lt;= SW;\n            if (saveAT) ATTEMPT &lt;= SW;\n        end\n    end\nendmodule<\/code><\/pre>\n<h2>FSM State Diagram<\/h2>\n<p>Here\u2019s a conceptual sketch of the Moore FSM for your safe:<\/p>\n<p>\u7a0b\u5f0f\u78bc<\/p>\n<pre><code>            +------------------+\n            |                  |\n            |      OPEN        |\n            |  Display: _OPEn_ |\n            +--------+---------+\n                     |\n                     | ENTER pressed\n                     v\n        +------------+-------------+\n        |                          |\n        |   WAIT_OPEN_RELEASE      |\n        | (wait for ENTER release) |\n        +------------+-------------+\n                     |\n                     v\n            +--------+---------+\n            |                  |\n            |     LOCKED       |\n            |  Display: LOCHED |\n            +--------+---------+\n                     |\n                     | ENTER pressed\n                     v\n            +--------+---------+\n            |                  |\n            |   CHECK_MATCH    |\n            |  (ATTEMPT==PW?)  |\n            +--------+---------+\n                     |\n             +-------+-------+\n             |               |\n         MATCH=1         MATCH=0\n             |               |\n             v               v\n+------------------+     +--------+---------+\n| WAIT_LOCK_RELEASE|     |     LOCKED       |\n| (wait for release)|     |  Display: LOCHED|\n+------------------+     +------------------+\n             |\n             v\n         +---+---+\n         | OPEN  |\n         +-------+<\/code><\/pre>\n<h2>Karnaugh Map Setup<\/h2>\n<p>Let\u2019s assume you use 3 bits to encode states:<\/p>\n<table>\n<thead>\n<tr>\n<th>State<\/th>\n<th>Encoding<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>OPEN<\/td>\n<td>000<\/td>\n<\/tr>\n<tr>\n<td>WAIT_OPEN_RELEASE<\/td>\n<td>001<\/td>\n<\/tr>\n<tr>\n<td>LOCKED<\/td>\n<td>010<\/td>\n<\/tr>\n<tr>\n<td>CHECK_MATCH<\/td>\n<td>011<\/td>\n<\/tr>\n<tr>\n<td>WAIT_LOCK_RELEASE<\/td>\n<td>100<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>State Table Example<\/h3>\n<table>\n<thead>\n<tr>\n<th>Current State<\/th>\n<th>ENTER<\/th>\n<th>MATCH<\/th>\n<th>Next State<\/th>\n<th>savePW<\/th>\n<th>saveAT<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>OPEN<\/td>\n<td>0<\/td>\n<td>X<\/td>\n<td>OPEN<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>OPEN<\/td>\n<td>1<\/td>\n<td>X<\/td>\n<td>WAIT_OPEN_RELEASE<\/td>\n<td>1<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>WAIT_OPEN_REL<\/td>\n<td>0<\/td>\n<td>X<\/td>\n<td>LOCKED<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>LOCKED<\/td>\n<td>0<\/td>\n<td>X<\/td>\n<td>LOCKED<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>LOCKED<\/td>\n<td>1<\/td>\n<td>X<\/td>\n<td>CHECK_MATCH<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<\/tr>\n<tr>\n<td>CHECK_MATCH<\/td>\n<td>X<\/td>\n<td>0<\/td>\n<td>LOCKED<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>CHECK_MATCH<\/td>\n<td>X<\/td>\n<td>1<\/td>\n<td>WAIT_LOCK_RELEASE<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>WAIT_LOCK_REL<\/td>\n<td>0<\/td>\n<td>X<\/td>\n<td>OPEN<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Karnaugh Map for Next State Bits<\/h3>\n<p>Let\u2019s say you\u2019re solving for <code>NS[0]<\/code> (next state bit 0). You\u2019d fill in a 4-variable K-map using:<\/p>\n<ul>\n<li>Current state bits: <code>S2 S1 S0<\/code><\/li>\n<li>Inputs: <code>ENTER<\/code>, <code>MATCH<\/code><\/li>\n<\/ul>\n<p>Each cell in the K-map represents a combination of these inputs, and you fill in the value of <code>NS[0]<\/code> from the state table.<\/p>\n<p>Once filled, you simplify using grouping rules to extract the SOP (Sum of Products) expression.<\/p>\n<h2>HEX Display Logic<\/h2>\n<p>To display <code>&quot;LOCHED&quot;<\/code> and <code>&quot;_OPEn_&quot;<\/code>, you\u2019ll need a segment decoder for each character. For example:<\/p>\n<table>\n<thead>\n<tr>\n<th>Character<\/th>\n<th>HEX Code<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>L<\/td>\n<td>0b01110011<\/td>\n<\/tr>\n<tr>\n<td>O<\/td>\n<td>0b00111111<\/td>\n<\/tr>\n<tr>\n<td>C<\/td>\n<td>0b01001110<\/td>\n<\/tr>\n<tr>\n<td>H<\/td>\n<td>0b01110110<\/td>\n<\/tr>\n<tr>\n<td>E<\/td>\n<td>0b01111001<\/td>\n<\/tr>\n<tr>\n<td>D<\/td>\n<td>0b01011110<\/td>\n<\/tr>\n<tr>\n<td>_<\/td>\n<td>0b00001000<\/td>\n<\/tr>\n<tr>\n<td>P<\/td>\n<td>0b01110011<\/td>\n<\/tr>\n<tr>\n<td>n<\/td>\n<td>0b01010100<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>You can use a case statement inside an <code>always_comb<\/code> block to map each character to its 7-segment code.<\/p>\n<p>Would you like help writing that decoder module next? Or want to walk through a Karnaugh map example for one of the next-state bits?<\/p>\n<p>ok<\/p>\n<p>Great! Let\u2019s walk through two things: a Karnaugh map example for one next-state bit, and a segment decoder for displaying <code>&quot;LOCHED&quot;<\/code> and <code>&quot;_OPEn_&quot;<\/code> on HEX displays.<\/p>\n<h2>Karnaugh Map Example: Next-State Bit<\/h2>\n<p>Let\u2019s say we\u2019re solving for <code>NS[0]<\/code>, the least significant bit of the next state. Assume the current state is encoded as <code>S2 S1 S0<\/code>, and inputs are <code>ENTER<\/code> and <code>MATCH<\/code>.<\/p>\n<p>We\u2019ll build a 4-variable Karnaugh map:<\/p>\n<h3>Variables:<\/h3>\n<ul>\n<li><code>S2 S1 S0<\/code> \u2192 current state<\/li>\n<li><code>ENTER<\/code> \u2192 input<\/li>\n<li><code>MATCH<\/code> \u2192 input<\/li>\n<\/ul>\n<h3>Step 1: Fill the truth table<\/h3>\n<p>From your FSM state table, extract the value of <code>NS[0]<\/code> for each combination of inputs and current state.<\/p>\n<p>Example row:<\/p>\n<table>\n<thead>\n<tr>\n<th>S2<\/th>\n<th>S1<\/th>\n<th>S0<\/th>\n<th>ENTER<\/th>\n<th>MATCH<\/th>\n<th>NS[0]<\/th>\n<th><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>0<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<td>X<\/td>\n<td>1<\/td>\n<td>\u2190 OPEN \u2192 WAIT_OPEN_RELEASE<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Repeat for all transitions.<\/p>\n<h3>Step 2: Fill Karnaugh map<\/h3>\n<p>Use the truth table to populate the K-map. Group adjacent 1s to simplify.<\/p>\n<h3>Step 3: Extract SOP expression<\/h3>\n<p>From the groups, derive a simplified Boolean expression for <code>NS[0]<\/code>. For example:<\/p>\n<p>text<\/p>\n<pre><code>NS[0] = S2&#039; S1 ENTER + S2 S0&#039; MATCH<\/code><\/pre>\n<p>Repeat for <code>NS[1]<\/code> and <code>NS[2]<\/code>.<\/p>\n<h2>HEX Display Decoder<\/h2>\n<p>Let\u2019s create a decoder to display <code>&quot;LOCHED&quot;<\/code> and <code>&quot;_OPEn_&quot;<\/code>. Each HEX digit maps to a 7-segment code.<\/p>\n<h3>Segment Encoding Table<\/h3>\n<table>\n<thead>\n<tr>\n<th>Char<\/th>\n<th>HEX Code<\/th>\n<th>Segment<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>L<\/td>\n<td>7&#8217;h38<\/td>\n<td>0110000<\/td>\n<\/tr>\n<tr>\n<td>O<\/td>\n<td>7&#8217;h3F<\/td>\n<td>1111110<\/td>\n<\/tr>\n<tr>\n<td>C<\/td>\n<td>7&#8217;h39<\/td>\n<td>0111001<\/td>\n<\/tr>\n<tr>\n<td>H<\/td>\n<td>7&#8217;h76<\/td>\n<td>1110110<\/td>\n<\/tr>\n<tr>\n<td>E<\/td>\n<td>7&#8217;h79<\/td>\n<td>1111001<\/td>\n<\/tr>\n<tr>\n<td>D<\/td>\n<td>7&#8217;h5E<\/td>\n<td>1011110<\/td>\n<\/tr>\n<tr>\n<td>_<\/td>\n<td>7&#8217;h08<\/td>\n<td>0001000<\/td>\n<\/tr>\n<tr>\n<td>P<\/td>\n<td>7&#8217;h73<\/td>\n<td>1110011<\/td>\n<\/tr>\n<tr>\n<td>n<\/td>\n<td>7&#8217;h54<\/td>\n<td>1010100<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Decoder Module<\/h3>\n<p>verilog<\/p>\n<pre><code>function logic [7:0] char_to_hex(input logic [2:0] char_index, input logic locked);\n    case (char_index)\n        3&#039;d0: char_to_hex = locked ? 7&#039;h38 : 7&#039;h08; \/\/ L or _\n        3&#039;d1: char_to_hex = locked ? 7&#039;h3F : 7&#039;h73; \/\/ O or P\n        3&#039;d2: char_to_hex = locked ? 7&#039;h39 : 7&#039;h08; \/\/ C or _\n        3&#039;d3: char_to_hex = locked ? 7&#039;h76 : 7&#039;h79; \/\/ H or E\n        3&#039;d4: char_to_hex = locked ? 7&#039;h79 : 7&#039;h54; \/\/ E or n\n        3&#039;d5: char_to_hex = locked ? 7&#039;h5E : 7&#039;h08; \/\/ D or _\n        default: char_to_hex = 7&#039;h00;\n    endcase\nendfunction<\/code><\/pre>\n<h3>Usage in <code>safe<\/code> module<\/h3>\n<p>verilog<\/p>\n<pre><code>assign HEX5 = char_to_hex(3&#039;d0, locked);\nassign HEX4 = char_to_hex(3&#039;d1, locked);\nassign HEX3 = char_to_hex(3&#039;d2, locked);\nassign HEX2 = char_to_hex(3&#039;d3, locked);\nassign HEX1 = char_to_hex(3&#039;d4, locked);\nassign HEX0 = char_to_hex(3&#039;d5, locked);<\/code><\/pre>\n<p>You\u2019ll need to define <code>locked<\/code> as a signal from your FSM state.<\/p>\n<hr \/>\n<h2>Step-by-Step Implementation Plan<\/h2>\n<h3>1. FSM Inputs and Outputs<\/h3>\n<p><strong>Inputs:<\/strong><\/p>\n<ul>\n<li><code>CLK50<\/code>: System clock<\/li>\n<li><code>KEY[0]<\/code>: Active-low reset<\/li>\n<li><code>KEY[1]<\/code>: ENTER button<\/li>\n<li><code>SW[9:0]<\/code>: User input (password or attempt)<\/li>\n<\/ul>\n<p><strong>Outputs:<\/strong><\/p>\n<ul>\n<li><code>LEDR[9]<\/code>: MATCH = (<code>ATTEMPT == PASSWORD<\/code>)<\/li>\n<li><code>LEDR[8]<\/code>: PREMATCH = (<code>SW == PASSWORD<\/code>)<\/li>\n<li><code>LEDR[3:0]<\/code>: COUNT = <code>count_ones(ATTEMPT ^ PASSWORD)<\/code><\/li>\n<li><code>HEX0<\/code>: Displays <code>&quot;LOCHED&quot;<\/code> or <code>&quot;_OPEn_&quot;<\/code><\/li>\n<\/ul>\n<h4>Character Breakdown<\/h4>\n<table>\n<thead>\n<tr>\n<th>HEX Display<\/th>\n<th><code>&quot;LOCHED&quot;<\/code><\/th>\n<th><code>&quot;_OPEn_&quot;<\/code><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>HEX5<\/td>\n<td><code>&#039;L&#039;<\/code><\/td>\n<td><code>&#039;_&#039;<\/code><\/td>\n<\/tr>\n<tr>\n<td>HEX4<\/td>\n<td><code>&#039;O&#039;<\/code><\/td>\n<td><code>&#039;O&#039;<\/code><\/td>\n<\/tr>\n<tr>\n<td>HEX3<\/td>\n<td><code>&#039;C&#039;<\/code><\/td>\n<td><code>&#039;P&#039;<\/code><\/td>\n<\/tr>\n<tr>\n<td>HEX2<\/td>\n<td><code>&#039;H&#039;<\/code><\/td>\n<td><code>&#039;E&#039;<\/code><\/td>\n<\/tr>\n<tr>\n<td>HEX1<\/td>\n<td><code>&#039;E&#039;<\/code><\/td>\n<td><code>&#039;n&#039;<\/code><\/td>\n<\/tr>\n<tr>\n<td>HEX0<\/td>\n<td><code>&#039;D&#039;<\/code><\/td>\n<td><code>&#039;_&#039;<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>7 Seg. value:<\/h4>\n<table>\n<thead>\n<tr>\n<th>Char<\/th>\n<th>Segments 1 as light\uff0cbit order: (gfedcba)<\/th>\n<th>Hex Value, <br \/>invert since0 as light<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>&#039;L&#039;<\/code><\/td>\n<td><code>0111000<\/code><\/td>\n<td><code>~7&#039;h38<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;O&#039;<\/code><\/td>\n<td><code>0011111<\/code><\/td>\n<td><code>~7&#039;h3F<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;C&#039;<\/code><\/td>\n<td><code>0110111<\/code><\/td>\n<td><code>~7&#039;h67<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;H&#039;<\/code><\/td>\n<td><code>0111100<\/code><\/td>\n<td><code>~7&#039;h3C<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;E&#039;<\/code><\/td>\n<td><code>0110110<\/code><\/td>\n<td><code>~7&#039;h76<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;D&#039;<\/code><\/td>\n<td><code>0011110<\/code><\/td>\n<td><code>~7&#039;h3E<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;P&#039;<\/code><\/td>\n<td><code>0111001<\/code><\/td>\n<td><code>~7&#039;h79<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;n&#039;<\/code><\/td>\n<td><code>0101010<\/code><\/td>\n<td><code>~7&#039;h2A<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;_&#039;<\/code><\/td>\n<td><code>0001000<\/code><\/td>\n<td><code>~7&#039;h08<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>HEX5-0 control be:<\/h4>\n<pre><code class=\"language-verilog\">always_comb begin\n    if (CURRENT_STATE == LOCKED) begin\n        HEX5 = ~7&#039;h38; \/\/ L\n        HEX4 = ~7&#039;h3F; \/\/ 0 (0 as O)\n        HEX3 = ~7&#039;h67; \/\/ C\n        HEX2 = ~7&#039;h3C; \/\/ H (H as K)\n        HEX1 = ~7&#039;h76; \/\/ E\n        HEX0 = ~7&#039;h3E; \/\/ d (d as D)\n    end else begin \/\/ OPEN\n        HEX5 = ~7&#039;h08; \/\/ _\n        HEX4 = ~7&#039;h3F; \/\/ O\n        HEX3 = ~7&#039;h79; \/\/ P\n        HEX2 = ~7&#039;h76; \/\/ E\n        HEX1 = ~7&#039;h2A; \/\/ n\n        HEX0 = ~7&#039;h08; \/\/ _\n    end\nend\n<\/code><\/pre>\n<h3>2. Combinational Logic Block<\/h3>\n<pre><code class=\"language-verilog\">always_comb begin\n    MATCH    = (ATTEMPT == PASSWORD);\n    PREMATCH = (SW == PASSWORD);\n    COUNT    = $countones(ATTEMPT ^ PASSWORD); \/\/ or use a loop if $countones unsupported\n\n    LEDR[9]   = MATCH;\n    LEDR[8]   = PREMATCH;\n    LEDR[3:0] = COUNT;\nend<\/code><\/pre>\n<h3>3. Register Update Block<\/h3>\n<pre><code class=\"language-verilog\">always_ff @(posedge CLK50) begin\n    if (!KEY[0]) begin \/\/ synchronous reset\n        PASSWORD      &lt;= 10&#039;b0000000000;\n        ATTEMPT       &lt;= 10&#039;b1111111111;\n        CURRENT_STATE &lt;= OPEN;\n    end else begin\n        if (savePW)\n            PASSWORD &lt;= SW;\n        if (saveAT)\n            ATTEMPT &lt;= SW;\n    end\nend<\/code><\/pre>\n<h3>4. Manual FSM Design (Moore Model)<\/h3>\n<h4>State Definitions<\/h4>\n<table>\n<thead>\n<tr>\n<th>State<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>OPEN<\/code><\/td>\n<td>Safe is unlocked<\/td>\n<\/tr>\n<tr>\n<td><code>WAIT_OPEN<\/code><\/td>\n<td>Wait for ENTER release after storing PASSWORD<\/td>\n<\/tr>\n<tr>\n<td><code>LOCKED<\/code><\/td>\n<td>Safe is locked<\/td>\n<\/tr>\n<tr>\n<td><code>WAIT_LOCKED<\/code><\/td>\n<td>Wait for ENTER release after storing ATTEMPT<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h4>State Diagram<\/h4>\n<p>\u7a0b\u5f0f\u78bc<\/p>\n<pre><code>OPEN --(ENTER)--&gt; WAIT_OPEN --(release)--&gt; LOCKED\nLOCKED --(ENTER &amp; MATCH)--&gt; WAIT_LOCKED --(release)--&gt; OPEN<\/code><\/pre>\n<pre><code class=\"language-mermaid\">graph LR\nOPEN --&gt;|ENTER| WAIT_OPEN --&gt;|release| LOCKED\nLOCKED --&gt;|ENTER &amp; MATCH| WAIT_LOCKED --&gt;|release| OPEN\n<\/code><\/pre>\n<h4>State Encoding<\/h4>\n<pre><code class=\"language-verilog\">typedef enum logic [1:0] {\n    OPEN        = 2&#039;b00,\n    WAIT_OPEN   = 2&#039;b01,\n    LOCKED      = 2&#039;b10,\n    WAIT_LOCKED = 2&#039;b11\n} state_t;<\/code><\/pre>\n<h3>5. FSM Logic (Manual Gate-Level)<\/h3>\n<p>Use Karnaugh maps to derive SOP equations for next-state bits and outputs. Then implement them in <code>fsm_gates<\/code> using basic gates or <code>assign<\/code> statements.<\/p>\n<h3>6. FSM Logic (Behavioral)<\/h3>\n<pre><code class=\"language-verilog\">module fsm_verilog(\n    input logic CLK50, RESET, ENTER,\n    input logic MATCH,\n    output logic savePW, saveAT,\n    output logic [1:0] CURRENT_STATE\n);\n    typedef enum logic [1:0] {OPEN, WAIT_OPEN, LOCKED, WAIT_LOCKED} state_t;\n    state_t state, next_state;\n\n    always_ff @(posedge CLK50) begin\n        if (!RESET)\n            state &lt;= OPEN;\n        else\n            state &lt;= next_state;\n    end\n\n    always_comb begin\n        savePW = 0;\n        saveAT = 0;\n        case (state)\n            OPEN: begin\n                if (ENTER) begin\n                    savePW    = 1;\n                    next_state = WAIT_OPEN;\n                end else\n                    next_state = OPEN;\n            end\n            WAIT_OPEN: next_state = (ENTER) ? WAIT_OPEN : LOCKED;\n\n            LOCKED: begin\n                if (ENTER &amp;&amp; MATCH) begin\n                    saveAT    = 1;\n                    next_state = WAIT_LOCKED;\n                end else\n                    next_state = LOCKED;\n            end\n            WAIT_LOCKED: next_state = (ENTER) ? WAIT_LOCKED : OPEN;\n        endcase\n    end\n\n    assign CURRENT_STATE = state;\nendmodule<\/code><\/pre>\n<h3>7. Top-Level Module <code>safe<\/code><\/h3>\n<pre><code class=\"language-verilogverilog\">module safe(\n    input logic CLK50,\n    input logic [1:0] KEY,\n    input logic [9:0] SW,\n    output logic [9:0] LEDR,\n    output logic [7:0] HEX5, HEX4, HEX3, HEX2, HEX1, HEX0\n);\n    logic [9:0] PASSWORD, ATTEMPT;\n    logic MATCH, PREMATCH;\n    logic [3:0] COUNT;\n    logic savePW, saveAT;\n    logic [1:0] CURRENT_STATE;\n\n    \/\/ Instantiate FSM\n    fsm_verilog fsm_inst(\n        .CLK50(CLK50),\n        .RESET(KEY[0]),\n        .ENTER(KEY[1]),\n        .MATCH(MATCH),\n        .savePW(savePW),\n        .saveAT(saveAT),\n        .CURRENT_STATE(CURRENT_STATE)\n    );\n\n    \/\/ Register logic\n    always_ff @(posedge CLK50) begin\n        if (!KEY[0]) begin\n            PASSWORD &lt;= 10&#039;b0000000000;\n            ATTEMPT  &lt;= 10&#039;b1111111111;\n        end else begin\n            if (savePW) PASSWORD &lt;= SW;\n            if (saveAT) ATTEMPT  &lt;= SW;\n        end\n    end\n\n    \/\/ Combinational logic\n    always_comb begin\n        MATCH    = (ATTEMPT == PASSWORD);\n        PREMATCH = (SW == PASSWORD);\n        COUNT    = $countones(ATTEMPT ^ PASSWORD);\n\n        LEDR[9]   = MATCH;\n        LEDR[8]   = PREMATCH;\n        LEDR[3:0] = COUNT;\n    end\n\n    \/\/ HEX0 display logic (simplified)\n    assign HEX0 = (CURRENT_STATE == LOCKED) ? 8&#039;hDE : 8&#039;h0E; \/\/ placeholder for LOCHED\/_OPEn_\nendmodule<\/code><\/pre>\n<p>Would you like help generating the HEX segment decoder for <code>&quot;LOCHED&quot;<\/code> and <code>&quot;_OPEn_&quot;<\/code> or visualizing the FSM diagram? I can also walk you through Karnaugh map derivation if you&#8217;re tackling the manual gate-level version.<\/p>\n<p>HEX5 to HEX0\uff1a user interface, displays <code>LOCHED<\/code> or <code>_OPEn_<\/code><\/p>\n<p>To display <code>&quot;LOCHED&quot;<\/code> or <code>&quot;_OPEn_&quot;<\/code> across HEX5 to HEX0, you&#8217;ll need to drive each 7-segment display with the correct segment encoding for each character. Here&#8217;s how you can implement it in SystemVerilog:<\/p>\n<h2>Segment Mapping for <code>&quot;LOCHED&quot;<\/code> and <code>&quot;_OPEn_&quot;<\/code><\/h2>\n<p>Each HEX display shows one ASCII-like character using 7 segments. We&#8217;ll define segment encodings for each character.<\/p>\n<h3>Character Breakdown<\/h3>\n<table>\n<thead>\n<tr>\n<th>HEX Display<\/th>\n<th><code>&quot;LOCHED&quot;<\/code><\/th>\n<th><code>&quot;_OPEn_&quot;<\/code><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>HEX5<\/td>\n<td><code>&#039;L&#039;<\/code><\/td>\n<td><code>&#039;_&#039;<\/code><\/td>\n<\/tr>\n<tr>\n<td>HEX4<\/td>\n<td><code>&#039;O&#039;<\/code><\/td>\n<td><code>&#039;O&#039;<\/code><\/td>\n<\/tr>\n<tr>\n<td>HEX3<\/td>\n<td><code>&#039;C&#039;<\/code><\/td>\n<td><code>&#039;P&#039;<\/code><\/td>\n<\/tr>\n<tr>\n<td>HEX2<\/td>\n<td><code>&#039;H&#039;<\/code><\/td>\n<td><code>&#039;E&#039;<\/code><\/td>\n<\/tr>\n<tr>\n<td>HEX1<\/td>\n<td><code>&#039;E&#039;<\/code><\/td>\n<td><code>&#039;n&#039;<\/code><\/td>\n<\/tr>\n<tr>\n<td>HEX0<\/td>\n<td><code>&#039;D&#039;<\/code><\/td>\n<td><code>&#039;_&#039;<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Segment Encoding (Common Active-Low)<\/h3>\n<p>Each character maps to a 7-bit pattern for segments A\u2013G. Here&#8217;s a sample encoding table:<\/p>\n<table>\n<thead>\n<tr>\n<th>Char<\/th>\n<th>Segments (gfedcba)<\/th>\n<th>Hex Value<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>&#039;L&#039;<\/code><\/td>\n<td><code>0111000<\/code><\/td>\n<td><code>7&#039;h38<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;O&#039;<\/code><\/td>\n<td><code>0011111<\/code><\/td>\n<td><code>7&#039;h3F<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;C&#039;<\/code><\/td>\n<td><code>0110111<\/code><\/td>\n<td><code>7&#039;h67<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;H&#039;<\/code><\/td>\n<td><code>0111100<\/code><\/td>\n<td><code>7&#039;h3C<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;E&#039;<\/code><\/td>\n<td><code>0110110<\/code><\/td>\n<td><code>7&#039;h76<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;D&#039;<\/code><\/td>\n<td><code>0011110<\/code><\/td>\n<td><code>7&#039;h3E<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;P&#039;<\/code><\/td>\n<td><code>0111001<\/code><\/td>\n<td><code>7&#039;h79<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;n&#039;<\/code><\/td>\n<td><code>0101010<\/code><\/td>\n<td><code>7&#039;h2A<\/code><\/td>\n<\/tr>\n<tr>\n<td><code>&#039;_&#039;<\/code><\/td>\n<td><code>0001000<\/code><\/td>\n<td><code>7&#039;h08<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<blockquote>\n<p>Note: These encodings assume active-low segments. You may need to invert them (<code>~<\/code>) depending on your board.<\/p>\n<\/blockquote>\n<h3>SystemVerilog Implementation<\/h3>\n<pre><code class=\"language-verilog\">always_comb begin\n    if (CURRENT_STATE == LOCKED) begin\n        HEX5 = ~7&#039;h38; \/\/ L\n        HEX4 = ~7&#039;h3F; \/\/ O\n        HEX3 = ~7&#039;h67; \/\/ C\n        HEX2 = ~7&#039;h3C; \/\/ H\n        HEX1 = ~7&#039;h76; \/\/ E\n        HEX0 = ~7&#039;h3E; \/\/ D\n    end else begin \/\/ OPEN\n        HEX5 = ~7&#039;h08; \/\/ _\n        HEX4 = ~7&#039;h3F; \/\/ O\n        HEX3 = ~7&#039;h79; \/\/ P\n        HEX2 = ~7&#039;h76; \/\/ E\n        HEX1 = ~7&#039;h2A; \/\/ n\n        HEX0 = ~7&#039;h08; \/\/ _\n    end\nend<\/code><\/pre>\n<p>Would you like a visual layout of the 7-segment characters or help testing this on your FPGA board? I can also help you write a reusable decoder module if you want to support more characters.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lab 5: Combination Lock Part 1 Modified from Digital De&#8230; &raquo; <a class=\"read-more-link\" href=\"https:\/\/vm1.go2see.me\/?p=1045\">\u95b1\u8b80\u5168\u6587<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[],"class_list":["post-1045","post","type-post","status-publish","format-standard","hentry","category-21"],"_links":{"self":[{"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/posts\/1045","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1045"}],"version-history":[{"count":5,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/posts\/1045\/revisions"}],"predecessor-version":[{"id":1047,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=\/wp\/v2\/posts\/1045\/revisions\/1047"}],"wp:attachment":[{"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1045"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1045"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vm1.go2see.me\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1045"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}