diff --git a/examples/example.vhdl b/examples/example.vhdl index 4e0a3f3..8ff64bf 100644 --- a/examples/example.vhdl +++ b/examples/example.vhdl @@ -9,10 +9,8 @@ port ( btn: in std_logic_vector(31 downto 0); sw: in std_logic_vector(31 downto 0); led: out std_logic_vector(31 downto 0) := (others => '0'); - seg0: out std_logic_vector(31 downto 0); - seg1: out std_logic_vector(31 downto 0); - seg2: out std_logic_vector(31 downto 0); - seg3: out std_logic_vector(31 downto 0) + segv: out std_logic_vector(31 downto 0); + segs: out std_logic_vector(31 downto 0) ); end circuit; diff --git a/libvhdl_conn/src/lib.rs b/libvhdl_conn/src/lib.rs index edcef09..9f8a885 100644 --- a/libvhdl_conn/src/lib.rs +++ b/libvhdl_conn/src/lib.rs @@ -1,22 +1,23 @@ use std::{ io::{BufRead, BufReader}, - sync::atomic::{AtomicU8, AtomicU32, AtomicU64, Ordering}, + sync::atomic::{AtomicU32, AtomicU64, Ordering}, }; -pub struct SimState{ +pub struct SimState { switch: AtomicU32, button: AtomicU32, led: AtomicU32, - segs: [AtomicU32; 4], - updated: AtomicU8, + /// represents 4 segments (each byte being one segment) + segs: [AtomicU32; 8], + updated: AtomicU32, } -static STATE: SimState = SimState{ +static STATE: SimState = SimState { switch: AtomicU32::new(0), button: AtomicU32::new(0), led: AtomicU32::new(0), - segs: [const{AtomicU32::new(0)}; 4], - updated: AtomicU8::new(0) + segs: [const { AtomicU32::new(0) }; 8], + updated: AtomicU32::new(0), }; /// default 1 ms @@ -34,13 +35,15 @@ fn client() { if let Ok(n) = v.parse::() { STATE.button.store(n, Ordering::Relaxed); } - } else if let value = STATE.updated.swap(0, Ordering::Relaxed) && value!=0 { - if (value >> 0) & 1 == 1{ + } else if let value = STATE.updated.swap(0, Ordering::Relaxed) + && value != 0 + { + if (value >> 0) & 1 == 1 { eprintln!("led={}", STATE.led.load(Ordering::Relaxed)); } - for i in 0..4{ - if (value >> (i+1)) & 1 == 1{ - eprintln!("seg{i}={}", STATE.segs[i].load(Ordering::Relaxed)); + for i in 0..STATE.segs.len() { + if (value >> (i + 1)) & 1 == 1 { + eprintln!("seg={};{i}", STATE.segs[i].load(Ordering::Relaxed)); } } } @@ -49,12 +52,15 @@ fn client() { #[unsafe(no_mangle)] pub extern "C" fn ffi_init() { - std::thread::Builder::new().name("client".into()).spawn(client).expect("Failed to spawn client thread"); - for arg in std::env::args(){ - if let Some(arg) = arg.strip_prefix("--cycle_sleep").or(arg.strip_prefix("-c")){ - if let Ok(nanos) = arg.trim().parse::(){ + std::thread::Builder::new() + .name("client".into()) + .spawn(client) + .expect("Failed to spawn client thread"); + for arg in std::env::args() { + if let Some(arg) = arg.strip_prefix("--cycle_sleep").or(arg.strip_prefix("-c")) { + if let Ok(nanos) = arg.trim().parse::() { SLEEP_NANOS.store(nanos, Ordering::Relaxed); - }else{ + } else { eprintln!("cycle sleep(ns) failed to parse"); } } @@ -73,22 +79,19 @@ pub extern "C" fn ffi_get_btn() -> u32 { } #[unsafe(no_mangle)] -pub extern "C" fn ffi_set_outputs(led: u32, seg0: u32, seg1: u32, seg2: u32, seg3: u32) { +pub extern "C" fn ffi_set_outputs(led: u32, segv: u32, segs: u32) { let o_led = STATE.led.swap(led, Ordering::Relaxed) != led; - let o_seg0 = STATE.segs[0].swap(seg0, Ordering::Relaxed) != seg0; - let o_seg1 = STATE.segs[1].swap(seg1, Ordering::Relaxed) != seg1; - let o_seg2 = STATE.segs[2].swap(seg2, Ordering::Relaxed) != seg2; - let o_seg3 = STATE.segs[3].swap(seg3, Ordering::Relaxed) != seg3; + let mut to_set = o_led as u32; - let to_set = (o_led as u8) << 0 - | (o_seg0 as u8) << 1 - | (o_seg1 as u8) << 2 - | (o_seg2 as u8) << 3 - | (o_seg3 as u8) << 4; + if let Some(place) = STATE.segs.get(segs as usize) { + let seg = place.swap(segv, Ordering::Relaxed) != segv; + to_set |= (seg as u32 + 1) << segs + } STATE.updated.fetch_or(to_set, Ordering::Relaxed); - - std::thread::sleep(std::time::Duration::from_nanos(SLEEP_NANOS.load(Ordering::Relaxed))); -} + std::thread::sleep(std::time::Duration::from_nanos( + SLEEP_NANOS.load(Ordering::Relaxed), + )); +} diff --git a/relay/src/build.rs b/relay/src/build.rs index dab2b3e..5df5e99 100644 --- a/relay/src/build.rs +++ b/relay/src/build.rs @@ -1,5 +1,8 @@ use std::{ - collections::HashMap, ffi::OsStr, ops::Deref, path::{Path, PathBuf} + collections::HashMap, + ffi::OsStr, + ops::Deref, + path::{Path, PathBuf}, }; use tokio::process::{Child, Command}; @@ -46,9 +49,7 @@ impl AsRef for TempDir { } } -pub async fn copy_and_build( - files: HashMap, -) -> HResult { +pub async fn copy_and_build(files: HashMap) -> HResult { use std::hash::*; let mut hasher = std::hash::DefaultHasher::default(); for (key, value) in &files { @@ -73,19 +74,18 @@ pub async fn copy_and_build( Ok(work_dir) } - -pub async fn build(build: &Path, src: &Path) -> HResult<()>{ +pub async fn build(build: &Path, src: &Path) -> HResult<()> { std::fs::create_dir_all(build)?; let embedded_lib_path = build.join("libvhdl_conn.a"); let embedded_tb_path = build.join("tb.vhdl"); std::fs::write(&embedded_lib_path, EMBEDDED_VHDL_UI_LIB)?; std::fs::write(&embedded_tb_path, EMBEDDED_TB_VHDL)?; - let mut cmd = Command::new("ghdl"); + let mut cmd = Command::new("ghdl"); cmd.kill_on_drop(true); cmd.args(["-i", "-g", "--std=08"]); - for file in src.read_dir().unwrap().flatten(){ + for file in src.read_dir().unwrap().flatten() { if Path::new(&file.file_name()).extension() == Some(OsStr::new("vhdl")) { cmd.arg(file.path().canonicalize()?); } @@ -99,7 +99,6 @@ pub async fn build(build: &Path, src: &Path) -> HResult<()>{ cmd.current_dir(build); ensure_ok(cmd.spawn()?).await?; - let mut cmd = Command::new("ghdl"); cmd.kill_on_drop(true); cmd.args(["-m", "--std=08"]); @@ -113,6 +112,6 @@ pub async fn build(build: &Path, src: &Path) -> HResult<()>{ .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()); ensure_ok(cmd.spawn()?).await?; - + Ok(()) } diff --git a/relay/src/main.rs b/relay/src/main.rs index d16a557..cf78c22 100644 --- a/relay/src/main.rs +++ b/relay/src/main.rs @@ -29,7 +29,10 @@ async fn serve_styles() -> impl IntoResponse { async fn serve_app_js() -> impl IntoResponse { ( - [(header::CONTENT_TYPE, "application/javascript; charset=utf-8")], + [( + header::CONTENT_TYPE, + "application/javascript; charset=utf-8", + )], UI_APP_JS, ) } @@ -91,7 +94,8 @@ fn parse_config_from_args() -> Result { } "--help" | "-h" => { return Err( - "usage: relay [--ip ] [--port ] [--update-ms ] [--workspace]".into(), + "usage: relay [--ip ] [--port ] [--update-ms ] [--workspace]" + .into(), ); } _ => { @@ -116,30 +120,24 @@ async fn main() { }; let update_interval = Duration::from_millis(cfg.update_ms); - let mut app = Router::new() - .route( - "/", - get(move || { - async move { serve_index().await } - }), - ) - .route( - "/index.html", - get(move || { - async move { serve_index().await } - }), - ) - .route("/styles.css", get(serve_styles)) - .route("/app.js", get(serve_app_js)) - .route( - "/ws/uploaded", - get(move |ws: WebSocketUpgrade| { - let update_interval = update_interval; - async move { - ws.on_upgrade(move |socket| uploaded::ws_handler(socket, update_interval)) - } - }), - ); + let mut app = + Router::new() + .route("/", get(move || async move { serve_index().await })) + .route( + "/index.html", + get(move || async move { serve_index().await }), + ) + .route("/styles.css", get(serve_styles)) + .route("/app.js", get(serve_app_js)) + .route( + "/ws/uploaded", + get(move |ws: WebSocketUpgrade| { + let update_interval = update_interval; + async move { + ws.on_upgrade(move |socket| uploaded::ws_handler(socket, update_interval)) + } + }), + ); if cfg.workspace_ws { app = app.route( @@ -183,10 +181,7 @@ pub enum ServerMsg<'a> { Start, Stop, Led(u32), - Seg0(u32), - Seg1(u32), - Seg2(u32), - Seg3(u32), + Seg { value: u32, index: u32 }, } pub type HResult = Result>; diff --git a/relay/src/uploaded.rs b/relay/src/uploaded.rs index 4d12871..c5703bd 100644 --- a/relay/src/uploaded.rs +++ b/relay/src/uploaded.rs @@ -1,12 +1,9 @@ -use axum::{ - extract::ws::{Message, WebSocket}, -}; -use futures_util::{ - SinkExt, StreamExt, -}; +use axum::extract::ws::{Message, WebSocket}; +use futures_util::{SinkExt, StreamExt}; use std::{collections::HashMap, time::Duration}; use tokio::{ - io::{AsyncBufReadExt, BufReader}, time::Instant, + io::{AsyncBufReadExt, BufReader}, + time::Instant, }; use crate::{ClientMsg, HResult, ServerMsg, build, run}; @@ -16,27 +13,30 @@ pub async fn ws_handler(socket: WebSocket, refresh_time: Duration) { let files = if let Some(Ok(Message::Text(msg))) = receiver.next().await && let Ok(files) = serde_json::from_str::<'_, HashMap>(&msg) - { + { files } else { return; }; - - let artifact_dir = match build::copy_and_build(files).await{ + let artifact_dir = match build::copy_and_build(files).await { Ok(dir) => dir, Err(err) => { - _ = sender.send(Message::Text(format!("Failed to build: {err}").into())).await; + _ = sender + .send(Message::Text(format!("Failed to build: {err}").into())) + .await; return; - }, + } }; - let mut process = match run::run(&artifact_dir).await{ + let mut process = match run::run(&artifact_dir).await { Ok(process) => process, Err(err) => { - _ = sender.send(Message::Text(format!("Failed to run: {err}").into())).await; + _ = sender + .send(Message::Text(format!("Failed to run: {err}").into())) + .await; return; - }, + } }; let mut sout = BufReader::new(process.stdout).lines(); let mut serr = BufReader::new(process.stderr).lines(); @@ -44,7 +44,7 @@ pub async fn ws_handler(socket: WebSocket, refresh_time: Duration) { let artifact_prefix = artifact_dir.to_str().unwrap_or("\0\0NOPE"); let mut print_deadline = Instant::now(); - + let result: HResult<()> = async { loop{ tokio::select! { @@ -89,14 +89,12 @@ pub async fn ws_handler(socket: WebSocket, refresh_time: Duration) { Ok(Some(line)) => { let msg = if let Some(repr) = line.strip_prefix("led="){ ServerMsg::Led(repr.parse().unwrap_or(0)) - }else if let Some(repr) = line.strip_prefix("seg0="){ - ServerMsg::Seg0(repr.parse().unwrap_or(0)) - }else if let Some(repr) = line.strip_prefix("seg1="){ - ServerMsg::Seg1(repr.parse().unwrap_or(0)) - }else if let Some(repr) = line.strip_prefix("seg2="){ - ServerMsg::Seg2(repr.parse().unwrap_or(0)) - }else if let Some(repr) = line.strip_prefix("seg3="){ - ServerMsg::Seg3(repr.parse().unwrap_or(0)) + }else if let Some(repr) = line.strip_prefix("seg=") + && let Some((val, idx)) = repr.split_once(";") { + ServerMsg::Seg{ + value: val.parse().unwrap_or(0), + index: idx.parse().unwrap_or(0) + } }else{ ServerMsg::Log { stream: "stderr", @@ -121,10 +119,10 @@ pub async fn ws_handler(socket: WebSocket, refresh_time: Duration) { Ok(()) }.await; - match result{ - Ok(_) => {}, + match result { + Ok(_) => {} Err(err) => { _ = sender.send(Message::Text(format!("{err}").into())).await; - }, + } } } diff --git a/relay/src/workspace.rs b/relay/src/workspace.rs index 0ed0179..f99b540 100644 --- a/relay/src/workspace.rs +++ b/relay/src/workspace.rs @@ -1,5 +1,6 @@ use axum::{ - Error, extract::ws::{Message, WebSocket} + Error, + extract::ws::{Message, WebSocket}, }; use futures_util::{ SinkExt, StreamExt, @@ -8,12 +9,12 @@ use futures_util::{ use std::{path::PathBuf, time::Duration}; use tokio::{ io::{AsyncBufReadExt, BufReader, Lines}, - process::{Child, ChildStderr, ChildStdin, ChildStdout}, time::Instant, + process::{Child, ChildStderr, ChildStdin, ChildStdout}, + time::Instant, }; use crate::{ClientMsg, ServerMsg, build, run}; - struct Process { process: Child, @@ -22,7 +23,6 @@ struct Process { stdin: ChildStdin, } - struct Handler { sender: SplitSink, receiver: SplitStream, @@ -36,7 +36,6 @@ struct Handler { } impl Handler { - fn workspace(socket: WebSocket, build: PathBuf, src: PathBuf, refresh_time: Duration) -> Self { let (sender, receiver) = socket.split(); Self { @@ -55,7 +54,12 @@ impl Handler { stream: "stdout", line: msg.as_ref(), }; - _ = self.sender.send(Message::Text(serde_json::to_string(&msg).unwrap_or_default().into())).await; + _ = self + .sender + .send(Message::Text( + serde_json::to_string(&msg).unwrap_or_default().into(), + )) + .await; } pub async fn eprint(&mut self, msg: impl AsRef) { @@ -64,36 +68,51 @@ impl Handler { stream: "stderr", line: msg.as_ref(), }; - _ = self.sender.send(Message::Text(serde_json::to_string(&msg).unwrap_or_default().into())).await; + _ = self + .sender + .send(Message::Text( + serde_json::to_string(&msg).unwrap_or_default().into(), + )) + .await; } async fn stop_process(&mut self) { self.process = None; - _ = self.sender.send(Message::Text(serde_json::to_string(&ServerMsg::Stop).unwrap_or_default().into())).await; + _ = self + .sender + .send(Message::Text( + serde_json::to_string(&ServerMsg::Stop) + .unwrap_or_default() + .into(), + )) + .await; } async fn handle_websocket_msg(&mut self, msg: ClientMsg) { - match msg{ + match msg { ClientMsg::Start => self.run_program().await, ClientMsg::Stop => self.stop_process().await, ClientMsg::Input { switch, buttons } => { - if let Some(process) = &mut self.process{ + if let Some(process) = &mut self.process { use tokio::io::AsyncWriteExt; - _ = process.stdin.write_all(format!("btn={}\n", buttons).as_bytes()).await; - _ = process.stdin.write_all(format!("sw={}\n", switch).as_bytes()).await; + _ = process + .stdin + .write_all(format!("btn={}\n", buttons).as_bytes()) + .await; + _ = process + .stdin + .write_all(format!("sw={}\n", switch).as_bytes()) + .await; } - }, + } } } - async fn handle_websocket_receive( - &mut self, - msg: Option>, - ) -> bool { + async fn handle_websocket_receive(&mut self, msg: Option>) -> bool { match msg { Some(Ok(Message::Close(_))) => true, Some(Ok(Message::Text(msg))) => { - let msg = match serde_json::from_str(msg.as_str()){ + let msg = match serde_json::from_str(msg.as_str()) { Ok(msg) => msg, Err(err) => { self.eprint(format!("Client message error {err}")).await; @@ -107,7 +126,7 @@ impl Handler { Some(Err(err)) => { self.eprint(format!("Client websocket error {err}")).await; true - }, + } None => true, } } @@ -115,7 +134,7 @@ impl Handler { async fn run(&mut self) { loop { if let Some(process) = &mut self.process { - if let Ok(Some(_)) = process.process.try_wait(){ + if let Ok(Some(_)) = process.process.try_wait() { self.stop_process().await; continue; } @@ -143,14 +162,12 @@ impl Handler { Ok(Some(line)) => { let msg = if let Some(repr) = line.strip_prefix("led="){ ServerMsg::Led(repr.parse().unwrap_or(0)) - }else if let Some(repr) = line.strip_prefix("seg0="){ - ServerMsg::Seg0(repr.parse().unwrap_or(0)) - }else if let Some(repr) = line.strip_prefix("seg1="){ - ServerMsg::Seg1(repr.parse().unwrap_or(0)) - }else if let Some(repr) = line.strip_prefix("seg2="){ - ServerMsg::Seg2(repr.parse().unwrap_or(0)) - }else if let Some(repr) = line.strip_prefix("seg3="){ - ServerMsg::Seg3(repr.parse().unwrap_or(0)) + }else if let Some(repr) = line.strip_prefix("seg=") + && let Some((val, idx)) = repr.split_once(";") { + ServerMsg::Seg{ + value: val.parse().unwrap_or(0), + index: idx.parse().unwrap_or(0) + } }else{ self.eprint(line).await; continue; @@ -170,19 +187,18 @@ impl Handler { _ = process.stdin.write_all("\n".as_bytes()).await; } } - }else{ + } else { let res = self.receiver.next().await; - if self.handle_websocket_receive(res).await{ + if self.handle_websocket_receive(res).await { break; } } } } - async fn run_program(&mut self) { - + async fn run_program(&mut self) { match build::build(&self.build_dir, &self.src_dir).await { - Ok(_) => {}, + Ok(_) => {} Err(err) => { _ = self.eprint(format!("Failed to build: {err}")).await; return; @@ -200,13 +216,25 @@ impl Handler { let stderr = BufReader::new(process.stderr).lines(); let stdin = process.stdin; - _ = self.sender.send(Message::Text(serde_json::to_string(&ServerMsg::Start).unwrap_or_default().into())).await; - self.process = Some( - Process { process: process.child, stderr, stdout, stdin } - ) + _ = self + .sender + .send(Message::Text( + serde_json::to_string(&ServerMsg::Start) + .unwrap_or_default() + .into(), + )) + .await; + self.process = Some(Process { + process: process.child, + stderr, + stdout, + stdin, + }) } } pub async fn ws_handler(socket: WebSocket, refresh_time: Duration) { - Handler::workspace(socket, "./target".into(), "./src".into(), refresh_time).run().await; + Handler::workspace(socket, "./target".into(), "./src".into(), refresh_time) + .run() + .await; } diff --git a/relay/ui/app.js b/relay/ui/app.js index 99fcbf7..807c658 100644 --- a/relay/ui/app.js +++ b/relay/ui/app.js @@ -12,10 +12,8 @@ port ( btn: in std_logic_vector(31 downto 0); sw: in std_logic_vector(31 downto 0); led: out std_logic_vector(31 downto 0) := (others => '0'); - seg0: out std_logic_vector(31 downto 0); - seg1: out std_logic_vector(31 downto 0); - seg2: out std_logic_vector(31 downto 0); - seg3: out std_logic_vector(31 downto 0) + segv: out std_logic_vector(31 downto 0); + segs: out std_logic_vector(31 downto 0) ); end circuit; @@ -250,6 +248,8 @@ class OutputController { constructor({ ledRow, hexRow }) { this.ledRow = ledRow; this.hexRow = hexRow; + // Each backend segN value encodes 4 seven-segment displays, one byte each. + this.segDisplaysPerGroup = 4; this.ledEls = Array.from(this.ledRow.querySelectorAll(".led[data-bit]")); this.segDisplays = Array.from(this.hexRow.querySelectorAll(".sevenSeg[data-digit]")); @@ -275,37 +275,12 @@ class OutputController { return true; } - let handledSegment = false; - - // Row mapping: - // seg0 -> displays 0..7 - // seg1 -> displays 8..15 - // seg2 -> displays 16..23 - // seg3 -> displays 24..31 - for (let row = 0; row < 4; row += 1) { - const key = `seg${row}`; - if (parsed[key] === undefined) continue; - - const rowBytes = parseSegRowBytes(parsed[key]); - if (!rowBytes) continue; - - this.setSegRow(row, rowBytes); - handledSegment = true; - } - - // Backward-compat path for a single 32-bit value (fills first 4 displays). - if (!handledSegment && parsed.seg !== undefined) { - const bytes = parseHexDigits(Number(parsed.seg) >>> 0); - this.setSegRow(0, bytes); - handledSegment = true; - } - - if (handledSegment) { + if (parsed.seg !== undefined){ + const groupBytes = parseSegRowBytes(parsed.seg.value); + this.setSegGroup(parsed.seg.index, groupBytes); this.renderAllSegments(); return true; } - - return false; } setLeds(bitsU32) { @@ -329,9 +304,9 @@ class OutputController { } } - setSegRow(rowIndex, bytes) { - const base = rowIndex * 8; - for (let i = 0; i < 8; i += 1) { + setSegGroup(groupIndex, bytes) { + const base = groupIndex * this.segDisplaysPerGroup; + for (let i = 0; i < this.segDisplaysPerGroup; i += 1) { const dst = base + i; if (dst >= this.segBytes.length) break; this.segBytes[dst] = bytes[i] & 0xff; diff --git a/rtl/tb.vhdl b/rtl/tb.vhdl index f072a81..9105385 100644 --- a/rtl/tb.vhdl +++ b/rtl/tb.vhdl @@ -12,10 +12,8 @@ architecture sim of tb is signal btn : std_logic_vector(31 downto 0) := (others => '0'); signal sw : std_logic_vector(31 downto 0) := (others => '0'); signal led : std_logic_vector(31 downto 0) := (others => '0'); - signal seg0 : std_logic_vector(31 downto 0) := (others => '0'); - signal seg1 : std_logic_vector(31 downto 0) := (others => '0'); - signal seg2 : std_logic_vector(31 downto 0) := (others => '0'); - signal seg3 : std_logic_vector(31 downto 0) := (others => '0'); + signal segv : std_logic_vector(31 downto 0) := (others => '0'); + signal segs : std_logic_vector(31 downto 0) := (others => '0'); procedure ffi_init is @@ -37,7 +35,7 @@ architecture sim of tb is end function; attribute foreign of ffi_get_btn : function is "VHPIDIRECT ffi_get_btn"; - procedure ffi_set_outputs(led_i: integer; seg0_i: integer; seg1_i: integer; seg2_i: integer; seg3_i: integer) is + procedure ffi_set_outputs(led_i: integer; segv_i: integer; segs_i: integer) is begin end procedure; attribute foreign of ffi_set_outputs : procedure is @@ -63,10 +61,8 @@ begin btn => btn, sw => sw, led => led, - seg0 => seg0, - seg1 => seg1, - seg2 => seg2, - seg3 => seg3 + segv => segv, + segs => segs ); -- 500 Hz clock (2 ms period) @@ -91,10 +87,8 @@ begin ffi_set_outputs( to_integer(signed(clean_slv(led))), - to_integer(signed(clean_slv(seg0))), - to_integer(signed(clean_slv(seg1))), - to_integer(signed(clean_slv(seg2))), - to_integer(signed(clean_slv(seg3))) + to_integer(signed(clean_slv(segv))), + to_integer(signed(clean_slv(segs))) ); end loop; end process; diff --git a/src/cpu.vhdl b/src/cpu.vhdl index 32e695a..5de2743 100644 --- a/src/cpu.vhdl +++ b/src/cpu.vhdl @@ -9,10 +9,8 @@ port ( btn: in std_logic_vector(31 downto 0); sw: in std_logic_vector(31 downto 0); led: out std_logic_vector(31 downto 0); - seg0: out std_logic_vector(31 downto 0); - seg1: out std_logic_vector(31 downto 0); - seg2: out std_logic_vector(31 downto 0); - seg3: out std_logic_vector(31 downto 0) + segv: out std_logic_vector(31 downto 0); + segs: out std_logic_vector(31 downto 0) ); end circuit; @@ -71,11 +69,11 @@ architecture description of circuit is begin - seg0(6 downto 0) <= dec7seg(reg_out(7 downto 4)); - seg0(14 downto 8) <= dec7seg(reg_out(3 downto 0)); + segs(6 downto 0) <= dec7seg(reg_out(7 downto 4)); + segs(14 downto 8) <= dec7seg(reg_out(3 downto 0)); - seg0(22 downto 16) <= dec7seg(reg_pc(7 downto 4)); - seg0(30 downto 24) <= dec7seg(reg_pc(3 downto 0)); + segs(22 downto 16) <= dec7seg(reg_pc(7 downto 4)); + segs(30 downto 24) <= dec7seg(reg_pc(3 downto 0)); led(7 downto 0) <= std_logic_vector(reg_a); led(23 downto 16) <= std_logic_vector(reg_b);