Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| q = 0 | |
| q_bar = 1 | |
| history = [] | |
| def sr_latch(s, r): | |
| global q, q_bar, history | |
| s = int(s) | |
| r = int(r) | |
| if s == 1 and r == 1: | |
| state = "INVALID" | |
| elif s == 1 and r == 0: | |
| q, q_bar = 1, 0 | |
| state = "SET" | |
| elif s == 0 and r == 1: | |
| q, q_bar = 0, 1 | |
| state = "RESET" | |
| else: | |
| state = "HOLD" | |
| q_display = "X" if state == "INVALID" else str(q) | |
| q_bar_display = "X" if state == "INVALID" else str(q_bar) | |
| history.append(f"S={s}, R={r} => Q={q_display}, Q'={q_bar_display} [{state}]") | |
| log = "\n".join(history) | |
| return q_display, q_bar_display, state, log | |
| def reset_latch(): | |
| global q, q_bar, history | |
| q = 0 | |
| q_bar = 1 | |
| history = [] | |
| return "0", "1", "HOLD", "" | |
| custom_css = """ | |
| .gradio-container { | |
| max-width: 720px !important; | |
| margin: auto; | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; | |
| } | |
| h1 { | |
| color: #1a1a2e !important; | |
| font-size: 28px !important; | |
| font-weight: 700 !important; | |
| margin-bottom: 4px !important; | |
| } | |
| .subtitle { | |
| color: #5a5a6e !important; | |
| font-size: 15px !important; | |
| } | |
| .output-box textarea { | |
| font-size: 22px !important; | |
| font-weight: 600 !important; | |
| text-align: center !important; | |
| color: #1a1a2e !important; | |
| } | |
| .history-box textarea { | |
| font-family: "SF Mono", "Fira Code", "Consolas", monospace !important; | |
| font-size: 13px !important; | |
| color: #3a3a4e !important; | |
| } | |
| .truth-table-wrap table { | |
| font-size: 14px !important; | |
| } | |
| .truth-table-wrap th { | |
| color: #5a5a6e !important; | |
| font-weight: 600 !important; | |
| } | |
| .truth-table-wrap td { | |
| color: #1a1a2e !important; | |
| } | |
| button.primary { | |
| background: #1a1a2e !important; | |
| color: #ffffff !important; | |
| border: none !important; | |
| } | |
| button.primary:hover { | |
| background: #2a2a3e !important; | |
| } | |
| input[type="radio"]:checked { | |
| accent-color: #1a1a2e !important; | |
| } | |
| """ | |
| with gr.Blocks(title="SR Latch Simulator") as demo: | |
| gr.Markdown("# SR Latch Simulator") | |
| gr.Markdown( | |
| "Toggle the S (set) and R (reset) inputs and click Apply to observe the latch behavior.", | |
| elem_classes=["subtitle"], | |
| ) | |
| with gr.Row(): | |
| s_input = gr.Radio(choices=["0", "1"], value="0", label="S (Set)") | |
| r_input = gr.Radio(choices=["0", "1"], value="0", label="R (Reset)") | |
| with gr.Row(): | |
| apply_btn = gr.Button("Apply", variant="primary") | |
| reset_btn = gr.Button("Reset") | |
| with gr.Row(): | |
| q_output = gr.Textbox(label="Q", value="0", interactive=False, elem_classes=["output-box"]) | |
| q_bar_output = gr.Textbox(label="Q'", value="1", interactive=False, elem_classes=["output-box"]) | |
| state_output = gr.Textbox(label="State", value="HOLD", interactive=False, elem_classes=["output-box"]) | |
| gr.Markdown("### Truth Table") | |
| gr.Dataframe( | |
| value=[ | |
| ["0", "0", "Prev", "Prev", "Hold"], | |
| ["1", "0", "1", "0", "Set"], | |
| ["0", "1", "0", "1", "Reset"], | |
| ["1", "1", "X", "X", "Invalid"], | |
| ], | |
| headers=["S", "R", "Q", "Q'", "State"], | |
| interactive=False, | |
| elem_classes=["truth-table-wrap"], | |
| ) | |
| gr.Markdown("### History") | |
| history_box = gr.Textbox( | |
| label="Log", | |
| lines=6, | |
| interactive=False, | |
| elem_classes=["history-box"], | |
| ) | |
| apply_btn.click( | |
| fn=sr_latch, | |
| inputs=[s_input, r_input], | |
| outputs=[q_output, q_bar_output, state_output, history_box], | |
| ) | |
| reset_btn.click( | |
| fn=reset_latch, | |
| inputs=[], | |
| outputs=[q_output, q_bar_output, state_output, history_box], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch(css=custom_css, theme=gr.themes.Base()) |