32bit stack machine

This commit is contained in:
car
2026-03-07 23:45:11 -05:00
commit f6c326e70c
69 changed files with 49784 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
a.out
*~
\#*
*.vcd
*.log
*.json
.DS_Store
+49
View File
@@ -0,0 +1,49 @@
PROJECT = cpu
BOARD = tangnano20k
FAMILY = GW2A-18C
DEVICE = GW2AR-LV18QN88C8/I7
# Source files
VERILOG_SRC = cpu.v register_file.v sequencer.v alu.v sram_srom.v
TOP_MODULE = cpu
# Constraint file
CST = tangnano20k.cst
# Synthesis
$(PROJECT).json: $(VERILOG_SRC)
yosys -p "read_verilog $(VERILOG_SRC); \
synth_gowin -top $(TOP_MODULE) -json $@"
# Place & Route
$(PROJECT)_pnr.json: $(PROJECT).json
nextpnr-gowin --json $< \
--write $@ \
--device $(DEVICE) \
--family $(FAMILY) \
--cst $(CST)
# Generate bitstream
$(PROJECT).fs: $(PROJECT)_pnr.json
gowin_pack -d $(FAMILY) -o $@ $
# Program FPGA
load: $(PROJECT).fs
openFPGALoader -b $(BOARD) $
# Flash to FPGA
flash: $(PROJECT).fs
openFPGALoader -b $(BOARD) -f $
# Clean
clean:
rm -f $(PROJECT).json $(PROJECT)_pnr.json $(PROJECT).fs
tsim:
./uasm.py ucode.src
customasm -f readmemh,width:32 hope.asm -o sromr.hex
./revhex.py sromr.hex srom.hex
iverilog -o cpu_sim cpu_tb2.v cpu.v register_file.v alu.v sequencer.v sram_srom.v
./cpu_sim|more
.PHONY: load flash clean tsim
+1
View File
@@ -0,0 +1 @@
# 32-bit Microcoded Stack Machine
+31
View File
@@ -0,0 +1,31 @@
module alu
(input [31:0] i_a,
input [31:0] i_b,
input [3:0] i_op,
output o_zero,
output reg [31:0] o_y);
assign o_zero = (o_y == 0);
always @(*) begin
case (i_op)
4'b0000: o_y = i_a;
4'b0001: o_y = ~i_a;
4'b0010: o_y = i_a + i_b;
4'b0011: o_y = i_a - i_b;
4'b0100: o_y = {31'd0, i_a > i_b};
4'b0101: o_y = {31'd0, i_a < i_b};
4'b0110: o_y = {31'd0, $signed(i_a) > $signed(i_b)};
4'b0111: o_y = {31'd0, $signed(i_a) < $signed(i_b)};
4'b1000: o_y = i_a & i_b;
4'b1001: o_y = i_a | i_b;
4'b1010: o_y = i_a ^ i_b;
4'b1011: o_y = i_a << i_b[4:0];
4'b1100: o_y = i_a >>> i_b[4:0];
4'b1101: o_y = i_a * i_b;
4'b1110: o_y = {{24{i_a[7]}}, i_a[7:0]};
4'b1111: o_y = {{16{i_a[15]}}, i_a[15:0]};
default: o_y = i_a;
endcase
end
endmodule // alu
+42
View File
@@ -0,0 +1,42 @@
module bus_interface
(input i_clk,
input i_rst,
input [1:0] i_act,
input i_dir,
input [31:0] i_cpu_data,
input [31:0] i_cpu_addr,
output [31:0] o_cpu_data,
output o_cpu_we,
output o_rwait,
output o_wwait,
/* Wishbone */
input i_ack,
input [31:0] i_dat,
output [31:0] o_dat,
output [31:0] o_adr,
output o_we,
output o_cyc,
output o_stb,
output [1:0] o_sel);
wire [3:0] sel;
wire err;
assign {err, sel} = (i_act == 0) ? 5b'00000 :
(i_act == 1 && i_cpu_addr[1:0] == 2'b00) ? 5b'00001 :
(i_act == 1 && i_cpu_addr[1:0] == 2'b01) ? 5b'00010 :
(i_act == 1 && i_cpu_addr[1:0] == 2'b10) ? 5b'00100 :
(i_act == 1 && i_cpu_addr[1:0] == 2'b11) ? 5b'01000 :
(i_act == 2 && i_cpu_addr[1:0] == 2'b00) ? 5b'00011 :
(i_act == 2 && i_cpu_addr[1:0] == 2'b10) ? 5b'01100 :
(i_act == 3 && i_cpu_addr[1:0] == 2'b00) ? 5b'01111 :
5'b10000;
assign o_sel = sel;
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
end else begin
end
end
endmodule
+91
View File
@@ -0,0 +1,91 @@
module chargen
#(
parameter CHAR_WIDTH=8,
parameter CHAR_HEIGHT=8,
parameter COLS=80,
parameter ROWS=60)
(input i_clk,
input i_rst,
input i_de,
input i_hsync,
input i_vsync,
output o_r,
output o_g,
output o_b);
reg [7:0] fontrom [0:2047];
reg [19:0] pos;
reg [2:0] font_row_offset;
reg font_row_offset_lock;
reg [7:0] glyph_line;
reg [11:0] cram_addr;
reg [11:0] cram_addr_sol;
reg [6:0] line_counter;
wire [7:0] glyph_line_wire;
wire glyph_bit;
wire [11:0] font_index;
assign font_index = {cram_addr[7:0], font_row_offset};
assign glyph_bit = glyph_line[7];
assign o_r = glyph_bit;
assign o_g = glyph_bit;
assign o_b = cram_addr[0];
initial begin
$readmemh("/Users/car/Projects/hope/font.hex", fontrom);
end
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
glyph_line <= 0;
end else begin
if (pos[2:0] == 7) begin
glyph_line <= fontrom[font_index];
end else if (i_de) begin
glyph_line <= (glyph_line << 1);
end
end
end // always @ (posedge i_clk, posedge i_rst)
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
cram_addr <= 0;
cram_addr_sol <= 0;
line_counter <= 0;
end else if (i_hsync) begin
if (line_counter == 0) begin
cram_addr_sol <= cram_addr;
line_counter <= 0;
end else begin
cram_addr <= cram_addr_sol;
line_counter <= line_counter + 1;
end
end else if (pos[2:0] == 7)
cram_addr <= cram_addr + 1;
end
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
pos <= 0;
font_row_offset <= 0;
font_row_offset_lock <= 0;
end else begin
if (i_vsync) begin
pos <= 0;
font_row_offset <= 0;
end else if (i_de) begin
pos <= pos + 1;
end else begin
pos <= pos;
if (~font_row_offset_lock & i_hsync) begin
font_row_offset_lock <= 1;
font_row_offset <= font_row_offset + 1;
end else if (~i_hsync) begin
font_row_offset_lock <= 0;
end
end
end
end
endmodule
+45
View File
@@ -0,0 +1,45 @@
module chargen
#(parameter CHAR_WIDTH=8,
parameter CHAR_HEIGHT=8,
parameter COLS=80,
parameter ROWS=60)
(input i_clk,
input i_rst,
input i_de,
input [10:0] i_row,
input [10:0] i_col,
input [15:0] i_ram_data,
output [12:0] o_ram_addr,
output o_r,
output o_g,
output o_b);
reg [7:0] fontrom [0:2047];
reg [7:0] glyph_line;
wire glyph_bit;
wire [7:0] char_attr;
wire [7:0] char_char;
assign o_ram_addr = i_row[10:3] * COLS + i_col[10:3];
assign glyph_bit = glyph_line[CHAR_WIDTH-1];
assign char_char = i_ram_data[7:0];
assign char_attr = i_ram_data[15:8];
assign o_r = glyph_bit?char_attr[0]:char_attr[3];
assign o_g = glyph_bit?char_attr[1]:char_attr[4];
assign o_b = glyph_bit?char_attr[2]:char_attr[5];
initial begin
$readmemh("/Users/car/Projects/hope/font.hex", fontrom);
end
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
glyph_line <= 0;
end else if (i_col[2:0] == 0) begin
glyph_line <= fontrom[{char_char, i_row[2:0]}];
end else begin
glyph_line <= glyph_line << 1;
end
end // always @ (posedge i_clk, posedge i_rst)
endmodule
+32
View File
@@ -0,0 +1,32 @@
module charram
#(parameter COLS=80,
parameter ROWS=60)
(input i_clk,
input i_rst,
input [12:0] i_gen_addr,
input [12:0] i_cpu_addr,
input [15:0] i_cpu_data,
input i_cpu_we,
output [15:0] o_gen_data,
output [15:0] o_cpu_data);
localparam CELLS=COLS*ROWS;
reg [15:0] cram [0:CELLS-1];
integer i;
initial begin
$readmemh("/Users/car/Projects/hope/cram.hex", cram);
end
assign o_gen_data = cram[i_gen_addr];
assign o_cpu_data = cram[i_cpu_addr];
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
end else if (i_cpu_we) begin
cram[i_cpu_addr] <= i_cpu_data;
end
end
endmodule
+191
View File
@@ -0,0 +1,191 @@
module cpu
(input i_clk,
input i_rst_n,
input i_uart_rx,
output o_uart_tx,
/*
input i_ack,
input [31:0] i_dat,
output [31:0] o_dat,
output [31:0] o_adr,
output [3:0] o_sel,
output o_we,
output o_stb,
output o_cyc,
*/
output reg [5:0] o_led);
wire i_rst;
wire halt;
wire [8:0] seq_a;
wire [8:0] seq_y;
wire seq_cc;
wire alu_zero;
wire [3:0] alu_op;
wire [31:0] alu_a;
wire [31:0] alu_b;
wire [31:0] alu_y;
wire [2:0] rf_rd_addr;
wire rf_mdr_we;
wire [23:0] rf_rma_data;
wire [31:0] rf_mdr_data_r;
wire [31:0] rf_mdr_data_w;
wire [31:0] rf_rs2_data;
wire rf_we;
wire mem_rwait;
wire mem_wwait;
wire [1:0] mem_act;
wire srr_we;
wire srr_stb;
wire [31:0] srr_data;
wire [8:0] u_imm;
wire [1:0] u_seq_op;
wire u_seq_src;
wire u_seq_cce;
wire u_seq_cci;
wire u_alu_src;
wire [3:0] u_alu_op;
wire [2:0] u_rf_rs1;
wire [1:0] u_rf_rs2;
wire [2:0] u_rf_rd;
wire [1:0] u_rf_rma;
wire u_rf_we;
wire [1:0] u_mem_act;
wire u_mem_actsrc;
wire u_mem_dir;
reg [35:0] uinst;
reg phalt;
reg strobe;
(* ram_style = "block" *) reg [35:0] microcode_rom [511:0];
reg [11:0] mapping_rom [63:0];
initial begin
$readmemh("/Users/car/Projects/hope/ucode.hex", microcode_rom);
$readmemh("/Users/car/Projects/hope/umap.hex", mapping_rom);
end
assign i_rst = ~i_rst_n;
assign mem_rwait = 0;
assign mem_wwait = 0;
assign rf_we = u_rf_we; //&((u_mem_act != 2'b00)?~strobe:1);
assign {u_imm[8:0], u_seq_op[1:0], u_seq_src, u_seq_cce, u_seq_cci, u_alu_src, u_alu_op[3:0],
u_rf_rs1[2:0], u_rf_rs2[1:0], u_rf_rd[2:0], u_rf_rma[1:0], u_rf_we,
u_mem_act[1:0], u_mem_actsrc, u_mem_dir} = uinst;
/*
assign halt = (mem_wwait && u_rf_rd == 3'd4) ||
(mem_rwait && (u_seq_src || u_rf_rs1 == 3'd4 || u_rf_rs2 == 3'd4)) ||
((mem_wwait | mem_rwait) & (u_mem_act[0] | u_mem_act[1]));
*/
assign halt = (u_mem_act != 2'b00 && !strobe);
assign seq_cc = ~u_seq_cce | (u_seq_cce & (u_seq_cci ^ alu_zero));
assign seq_a = u_seq_src ? mapping_rom[rf_mdr_data_r[7:2]][8:0] : u_imm;
assign alu_b = rf_rs2_data;
assign rf_mdr_we = (rf_rma_data < 24'h008000) ? srr_we : 0;
assign rf_mdr_data_w = (rf_rma_data < 24'h008000) ? srr_data : 0;
assign alu_op = u_alu_src ? rf_rma_data[3:0] : u_alu_op;
assign mem_act = u_mem_actsrc ? rf_rma_data[1:0] : u_mem_act;
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
uinst <= 0;
strobe <= 0;
phalt <= 0;
end else begin
phalt <= halt;
if (u_mem_act != 2'b00 && !strobe) begin
strobe <= 1;
uinst <= uinst;
end else begin
strobe <= 0;
uinst <= microcode_rom[seq_y];
end
end
end
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) o_led <= 0;
else if (rf_rma_data == 28'h00F000 && u_mem_dir) o_led <= rf_mdr_data_w[7:0];
else o_led <= o_led;
end
register_file register_file_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.i_halt(halt),
.i_rs1_addr(u_rf_rs1),
.i_rs2_addr(u_rf_rs2),
.i_rd_addr(u_rf_rd),
.i_rma_addr(u_rf_rma),
.i_rd_data(alu_y),
.i_rd_we(rf_we),
.i_mdr_we(rf_mdr_we),
.i_mdr_data(rf_mdr_data_w),
.i_imm(u_imm),
.o_rs1_data(alu_a),
.o_rs2_data(rf_rs2_data),
.o_rma_data(rf_rma_data),
.o_mdr_data(rf_mdr_data_r));
alu alu_inst
(.i_a(alu_a),
.i_b(alu_b),
.i_op(alu_op),
.o_zero(alu_zero),
.o_y(alu_y));
sequencer sequencer_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.i_halt(halt),
.i_a(seq_a),
.i_op(u_seq_op),
.i_cc(seq_cc),
.o_y(seq_y));
sram_srom sram_srom_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.i_dir(u_mem_dir),
.i_act(mem_act),
.i_addr(rf_rma_data),
.i_data(rf_mdr_data_r),
.o_data(srr_data),
.o_we(srr_we),
.o_stb(srr_stb));
/*
bus_interface bus_interface_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.i_act(u_mem_act),
.i_dir(u_mem_dir),
.i_cpu_data(rf_mdr_data_r),
.i_cpu_addr(rf_rma_data),
.o_cpu_data(rf_mdr_data_w),
.o_cpu_we(rf_mdr_we),
.o_rwait(mem_rwait),
.o_wwait(mem_wwait),
.i_ack(i_ack),
.i_dat(i_dat),
.o_dat(o_dat),
.o_adr(o_adr),
.o_we(o_we),
.o_cyc(o_cyc),
.o_stb(o_stb),
.o_sel(o_sel));
*/
endmodule
Executable
+2186
View File
File diff suppressed because it is too large Load Diff
+237
View File
@@ -0,0 +1,237 @@
`timescale 1ns/1ps
module cpu_tb;
// Clock and reset
reg clk;
reg rst;
// Wishbone signals (unused but needed for module)
reg i_ack;
reg [31:0] i_dat;
wire [31:0] o_dat;
wire [31:0] o_adr;
wire [3:0] o_sel;
wire o_we;
wire o_stb;
wire o_cyc;
// Instantiate CPU
cpu dut (
.i_clk(clk),
.i_rst_n(rst)
/*.i_ack(i_ack),
.i_dat(i_dat),
.o_dat(o_dat),
.o_adr(o_adr),
.o_sel(o_sel),
.o_we(o_we),
.o_stb(o_stb),
.o_cyc(o_cyc)*/
);
// Clock generation - 50MHz (20ns period)
initial begin
clk = 0;
forever #10 clk = ~clk;
end
// Simulation control
initial begin
// Initialize
rst = 0;
//i_ack = 0;
//i_dat = 0;
// Dump waveforms
$dumpfile("cpu_tb.vcd");
$dumpvars(0, cpu_tb);
// Reset pulse
#50;
rst = 1;
// Run for some cycles
#10000;
$display("\n=== SIMULATION COMPLETE ===");
$finish;
end
// Monitor important signals
always @(posedge clk) begin
if (rst) begin
// Print state every cycle
$display("T=%0t | PC=0x%03X | HALT=%b | PCP=0x%08X DSP=0x%08X RSP=0x%08X TMP=0x%08X MDR=0x%08X TOS=0x%08X ACC=0x%08X",
$time,
dut.seq_y, // Microcode PC
dut.halt, // CPU halted?
dut.register_file_inst.registers[0], // PCP
dut.register_file_inst.registers[1], // DSP
dut.register_file_inst.registers[2], // RSP
dut.register_file_inst.registers[3], // TMP
dut.register_file_inst.registers[4], // MDR
dut.register_file_inst.registers[5], // TOS
dut.register_file_inst.registers[6] // ACC
);
// Decode current microinstruction
$display(" | uCode: imm=%03X seqop=%b seqsrc=%b aluop=%04b rs1=%d rs2=%d rd=%d rma=%d rwe=%b",
dut.u_imm,
dut.u_seq_op,
dut.u_seq_src,
dut.u_alu_op,
dut.u_rf_rs1,
dut.u_rf_rs2,
dut.u_rf_rd,
dut.u_rf_rma,
dut.u_rf_we
);
// Show ALU operation if register write is happening
if (dut.u_rf_we && !dut.halt) begin
$display(" | ALU: %08X %s %08X = %08X (zero=%b)",
dut.alu_a,
alu_op_name(dut.alu_op),
dut.alu_b,
dut.alu_y,
dut.alu_zero
);
end
// Show memory operations
if (dut.u_mem_act != 0) begin
$display(" | MEM: %s %s @ 0x%08X data=0x%08X",
(dut.u_mem_dir ? "WRITE" : "READ"),
mem_size_name(dut.u_mem_act),
dut.rf_rma_data,
(dut.u_mem_dir ? dut.rf_mdr_data_r : dut.rf_mdr_data_w)
);
end
$display(""); // Blank line between cycles
end
end
// Helper function to decode ALU operation names
function [63:0] alu_op_name;
input [3:0] op;
begin
case(op)
4'b0000: alu_op_name = "PASS ";
4'b0001: alu_op_name = "NOT ";
4'b0010: alu_op_name = "INC ";
4'b0011: alu_op_name = "DEC ";
4'b0100: alu_op_name = "ADD ";
4'b0101: alu_op_name = "SUB ";
4'b0110: alu_op_name = "GT ";
4'b0111: alu_op_name = "LT ";
4'b1000: alu_op_name = "AND ";
4'b1001: alu_op_name = "OR ";
4'b1010: alu_op_name = "XOR ";
4'b1011: alu_op_name = "LSL ";
4'b1100: alu_op_name = "ASR ";
4'b1101: alu_op_name = "MUL ";
4'b1110: alu_op_name = "INC4 ";
4'b1111: alu_op_name = "DEC4 ";
default: alu_op_name = "UNKNOWN ";
endcase
end
endfunction
// Helper function to decode memory size
function [39:0] mem_size_name;
input [1:0] size;
begin
case(size)
2'b00: mem_size_name = "NOP ";
2'b01: mem_size_name = "WORD ";
2'b10: mem_size_name = "HWORD";
2'b11: mem_size_name = "BYTE ";
default: mem_size_name = "?? ";
endcase
end
endfunction
// Detect interesting events
always @(posedge clk) begin
if (rst) begin
// Detect jumps
if (dut.u_seq_op != 2'b00 && dut.seq_cc) begin
case(dut.u_seq_op)
2'b01: $display(">>> JUMP to 0x%03X", dut.seq_a);
2'b10: $display(">>> RETURN to 0x%03X", dut.sequencer_inst.ra);
2'b11: $display(">>> CALL to 0x%03X (RA=0x%03X)",
dut.seq_a, dut.sequencer_inst.pc + 1);
endcase
end
// Detect execution of fetch loop
if (dut.seq_y == 9'h000) begin
$display(">>> FETCH instruction from PCP=0x%08X",
dut.register_file_inst.registers[0]);
end
// Detect init routine
if (dut.seq_y == 9'h1F0) begin
$display(">>> INIT routine started");
end
end
end
// Periodically dump register file state
integer cycle_count;
initial cycle_count = 0;
always @(posedge clk) begin
if (rst) begin
cycle_count = cycle_count + 1;
// Every 50 cycles, dump register state
if (cycle_count % 50 == 0) begin
$display("\n========== REGISTER DUMP (cycle %0d) ==========", cycle_count);
$display("PCP = 0x%08X (Program Counter)",
dut.register_file_inst.registers[0]);
$display("DSP = 0x%08X (Data Stack Pointer)",
dut.register_file_inst.registers[1]);
$display("RSP = 0x%08X (Return Stack Pointer)",
dut.register_file_inst.registers[2]);
$display("TMP = 0x%08X (Temporary)",
dut.register_file_inst.registers[3]);
$display("MDR = 0x%08X (Memory Data)",
dut.register_file_inst.registers[4]);
$display("TOS = 0x%08X (Top of Stack)",
dut.register_file_inst.registers[5]);
$display("ACC = 0x%08X (Accumulator)",
dut.register_file_inst.registers[6]);
$display("===============================================\n");
end
end
end
// Watchdog - detect infinite loops
reg [8:0] last_pc;
integer same_pc_count;
initial begin
last_pc = 9'h000;
same_pc_count = 0;
end
always @(posedge clk) begin
if (rst) begin
if (dut.seq_y == last_pc && !dut.halt) begin
same_pc_count = same_pc_count + 1;
if (same_pc_count > 100) begin
$display("\n!!! ERROR: CPU stuck at PC=0x%03X for %0d cycles !!!",
dut.seq_y, same_pc_count);
$display("This might be an infinite loop or missing microcode.");
$finish;
end
end else begin
last_pc = dut.seq_y;
same_pc_count = 0;
end
end
end
endmodule
+322
View File
@@ -0,0 +1,322 @@
`timescale 1ns / 1ps
module cpu_tb_enhanced;
// Clock and reset
reg clk;
reg rst_n;
reg uart_rx;
wire uart_tx;
wire [5:0] led;
// Instantiate the CPU
cpu dut (
.i_clk(clk),
.i_rst_n(rst_n),
.i_uart_rx(uart_rx),
.o_uart_tx(uart_tx),
.o_led(led)
);
// Clock generation - 10ns period (100MHz)
initial begin
clk = 0;
forever #5 clk = ~clk;
end
// ============================================================================
// HELPER FUNCTIONS FOR DISPLAY
// ============================================================================
function [63:0] reg_name;
input [2:0] addr;
begin
case (addr)
3'd0: reg_name = "PCP";
3'd1: reg_name = "DSP";
3'd2: reg_name = "RSP";
3'd3: reg_name = "TMP";
3'd4: reg_name = "MDR";
3'd5: reg_name = "TOS";
3'd6: reg_name = "ACC";
3'd7: reg_name = "IMM";
default: reg_name = "???";
endcase
end
endfunction
function [63:0] rma_name;
input [1:0] addr;
begin
case (addr)
2'd0: rma_name = "PCP";
2'd1: rma_name = "DSP";
2'd2: rma_name = "RSP";
2'd3: rma_name = "TMP";
default: rma_name = "???";
endcase
end
endfunction
function [63:0] alu_op_name;
input [3:0] op;
begin
case (op)
4'h0: alu_op_name = "A ";
4'h1: alu_op_name = "NOT ";
4'h2: alu_op_name = "ADD ";
4'h3: alu_op_name = "SUB ";
4'h4: alu_op_name = "SGT ";
4'h5: alu_op_name = "SLT ";
4'h6: alu_op_name = "GT ";
4'h7: alu_op_name = "LT ";
4'h8: alu_op_name = "AND ";
4'h9: alu_op_name = "OR ";
4'ha: alu_op_name = "XOR ";
4'hb: alu_op_name = "LSL ";
4'hc: alu_op_name = "ASR ";
4'hd: alu_op_name = "MUL ";
4'he: alu_op_name = "SEXTB ";
4'hf: alu_op_name = "SEXTH ";
default: alu_op_name = "??? ";
endcase
end
endfunction
function [63:0] seq_op_name;
input [1:0] op;
begin
case (op)
2'b00: seq_op_name = "STEP";
2'b01: seq_op_name = "JUMP";
2'b10: seq_op_name = "RTRN";
2'b11: seq_op_name = "CALL";
default: seq_op_name = "????";
endcase
end
endfunction
function [63:0] mem_act_name;
input [1:0] act;
begin
case (act)
2'b00: mem_act_name = "NOP ";
2'b01: mem_act_name = "WORD";
2'b10: mem_act_name = "HWRD";
2'b11: mem_act_name = "BYTE";
default: mem_act_name = "????";
endcase
end
endfunction
// ============================================================================
// MONITORING CONFIGURATION
// ============================================================================
parameter SHOW_UNCHANGED_REGS = 1; // Set to 1 to always show all registers
parameter SHOW_MEMORY_CONTENTS = 1; // Set to 1 to show memory around stack pointers
parameter MEM_CONTEXT_LINES = 4; // How many memory locations to show around SP
parameter COMPACT_MODE = 1; // Set to 1 for more compact output
// Previous register values for change detection
reg [31:0] prev_regs [0:6];
integer cycle;
// ============================================================================
// MAIN MONITOR
// ============================================================================
initial begin
cycle = 0;
for (integer i = 0; i < 7; i = i + 1)
prev_regs[i] = 0;
$display("\n");
$display("");
$display(" CPU EXECUTION MONITOR ");
$display("");
$display("\n");
end
always @(posedge clk) begin
if (rst_n) begin
cycle = cycle + 1;
if (!COMPACT_MODE) begin
$display("\n");
$display(" CYCLE %-5d ", cycle);
$display("");
end else begin
$display("\n CYCLE %-5d ", cycle);
end
// ============ SEQUENCER ============
if (!COMPACT_MODE) $display("\n SEQUENCER ");
else $display("\n[SEQ]");
$display(" PC=0x%03h 0x%03h RA=0x%03h %s %s%s%s",
dut.sequencer_inst.pc,
dut.seq_y,
dut.sequencer_inst.ra,
seq_op_name(dut.u_seq_op),
dut.u_seq_src ? "MAP" : "IMM",
dut.u_seq_cce ? $sformatf(" CC=%b", dut.seq_cc) : "",
dut.halt ? " [HALT]" : "");
if (!COMPACT_MODE) $display("");
// ============ MICROCODE ============
if (!COMPACT_MODE) $display("\n MICROCODE @ 0x%03h ", dut.sequencer_inst.pc);
else $display("\n[UCODE @ 0x%03h]", dut.sequencer_inst.pc);
$display(" Raw: 0x%09h IMM=0x%03h(%0d)", dut.uinst, dut.u_imm, dut.u_imm);
// Decode and display operation
$write(" Op: ");
// Register write operation
if (dut.u_rf_we && !dut.halt) begin
$write("%s ", reg_name(dut.u_rf_rd));
if (dut.u_alu_src)
$write("%s(%s,%s)[RMA[3:0]=0x%h]",
alu_op_name(dut.rf_rma_data[3:0]),
reg_name(dut.u_rf_rs1),
reg_name(dut.u_rf_rs2),
dut.rf_rma_data[3:0]);
else
$write("%s(%s,%s)",
alu_op_name(dut.u_alu_op),
reg_name(dut.u_rf_rs1),
reg_name(dut.u_rf_rs2));
end
// Memory operation
if (dut.u_mem_act != 2'b00) begin
if (dut.u_rf_we && !dut.halt) $write("; ");
if (dut.u_mem_dir)
$write("MEM[%s]=MDR %s", rma_name(dut.u_rf_rma), mem_act_name(dut.u_mem_act));
else
$write("MDRMEM[%s] %s", rma_name(dut.u_rf_rma), mem_act_name(dut.u_mem_act));
end
if (!dut.u_rf_we && dut.u_mem_act == 2'b00)
$write("NOP");
$display("");
if (!COMPACT_MODE) $display("");
// ============ REGISTERS ============
if (!COMPACT_MODE) $display("\n REGISTERS ");
else $display("\n[REGS]");
// Show registers with change indicators
for (integer i = 0; i < 7; i = i + 1) begin
if (SHOW_UNCHANGED_REGS ||
(i > 3 ? dut.register_file_inst.data_registers[i % 4] : dut.register_file_inst.addr_registers[i % 4]) != prev_regs[i] ||
(dut.u_rf_rd == i && dut.rf_we && !dut.halt)) begin
$write(" %s: 0x%08h", reg_name(i), (i > 3 ? dut.register_file_inst.data_registers[i % 4] : dut.register_file_inst.addr_registers[i % 4]));
if ((i > 3 ? dut.register_file_inst.data_registers[i % 4] : dut.register_file_inst.addr_registers[i % 4]) != prev_regs[i])
$write(" 0x%08h", prev_regs[i]);
$display("");
prev_regs[i] = (i > 3 ? dut.register_file_inst.data_registers[i % 4] : dut.register_file_inst.addr_registers[i % 4]);
end
end
if (!COMPACT_MODE) $display("");
// ============ ALU ============
if (!COMPACT_MODE) $display("\n ALU ");
else $display("\n[ALU]");
$display(" %s: A=0x%08h B=0x%08h Y=0x%08h Z=%b",
alu_op_name(dut.alu_op),
dut.alu_a,
dut.alu_b,
dut.alu_y,
dut.alu_zero);
if (!COMPACT_MODE) $display("");
// ============ MEMORY CONTENTS ============
if (SHOW_MEMORY_CONTENTS && dut.u_mem_act != 2'b00) begin
if (!COMPACT_MODE) $display("\n MEMORY ACCESS ");
else $display("\n[MEM]");
$display(" Addr: 0x%08h %s %s",
dut.rf_rma_data,
dut.u_mem_dir ? "WRITE" : "READ ",
mem_act_name(dut.u_mem_act));
if (dut.u_mem_dir)
$display(" Data: 0x%08h (from MDR)", dut.rf_mdr_data_r);
else
$display(" Data: 0x%08h (to MDR)", dut.srr_data);
if (!COMPACT_MODE) $display("");
end
// ============ STACK CONTEXT ============
if (SHOW_MEMORY_CONTENTS && !COMPACT_MODE) begin
$display("\n STACK CONTEXT ");
$display(" Data Stack (DSP=0x%08h):", dut.register_file_inst.registers[1]);
$display(" Return Stack (RSP=0x%08h):", dut.register_file_inst.registers[2]);
$display("");
end
// ============ OUTPUT ============
if (led != 0 || cycle < 10) begin
if (!COMPACT_MODE) $display("\n OUTPUT ");
else $display("\n[OUT]");
$display(" LED: 0x%02h (0b%06b)", led, led);
if (!COMPACT_MODE) $display("");
end
end
end
// ============================================================================
// TEST STIMULUS
// ============================================================================
initial begin
// Initialize signals
rst_n = 0;
uart_rx = 1;
// Wait for a few cycles
repeat(5) @(posedge clk);
// Release reset
rst_n = 1;
$display("\n*** RESET RELEASED ***\n");
// Run for specified number of cycles
repeat(500) @(posedge clk);
// End simulation
$display("\n");
$display("");
$display(" SIMULATION COMPLETE ");
$display(" Total Cycles: %-5d ", cycle);
$display("");
$display("\n");
$finish;
end
// Waveform dump
initial begin
$dumpfile("cpu_tb_enhanced.vcd");
$dumpvars(0, cpu_tb_enhanced);
end
// Timeout watchdog
initial begin
#200000; // 200us timeout
$display("\n*** SIMULATION TIMEOUT ***\n");
$finish;
end
endmodule
BIN
View File
Binary file not shown.
+4800
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
BBiigg CChhuunngguuss
Executable
BIN
View File
Binary file not shown.
+6
View File
@@ -0,0 +1,6 @@
#include <stdio.h>
void main() {
for (;;)
printf("Digital:0\nDigital:1\n");
}
BIN
View File
Binary file not shown.
+2048
View File
File diff suppressed because it is too large Load Diff
+123
View File
@@ -0,0 +1,123 @@
#subruledef reladdr {
{addr: u32} => {
reladdr = addr - $ - 2
assert(reladdr <= 0x7f)
assert(reladdr >= !0x7f)
reladdr`8
}
}
#ruledef
{
pass => 0x00
not => 0x01
times2 => 0x02
clrtos => 0x03
square => 0x0D
sextb => 0x0E
sexth => 0x0F
add => 0x12
sub => 0x13
gt => 0x14
lt => 0x15
sgt => 0x16
slt => 0x17
and => 0x18
or => 0x19
xor => 0x1A
shl => 0x1B
asr => 0x1C
mul => 0x1D
addi {n: u8} => 0x22 @ n
subi {n: u8} => 0x23 @ n
gti {n: u8} => 0x24 @ n
lti {n: u8} => 0x25 @ n
andi {n: u8} => 0x28 @ n
ori {n: u8} => 0x29 @ n
xori {n: u8} => 0x2A @ n
shli {n: u8} => 0x2B @ n
asri {n: u8} => 0x2C @ n
muli {n: u8} => 0x2D @ n
swap => 0x30
dup => 0x34
drop => 0x38
over => 0x3C
fetchdw => 0x40
fetchdb => 0x44
fetchrw => 0x48
fetchrb => 0x4C
storedw => 0x50
storedb => 0x54
pstoredw => 0x58
pstoredb => 0x5C
rtod => 0x60
dtor => 0x64
jump => 0x68
jumpz => 0x6C
jumpnz => 0x70
call => 0x74
callz => 0x78
callnz => 0x7C
ret => 0x80
retz => 0x84
retnz => 0x88
pushdb {n: u8} => 0x8C @ n
pushdr {n: reladdr} => 0x8C @ n @ 0x0E
pushdhu {n: u16} => 0x90 @ n
pushdwu {n: u32} => 0x94 @ n
pushdha {n: u16} => 0x98 @ n
pushdwa {n: u32} => 0x9C @ n
repeati {n: reladdr} => 0xA0 @ n
db {n: u8} => n
dh {n: u16} => n
dd {n: u32} => n
}
pushdb 8
start: pushdb 0x8
pushdb fiter
call
pushdb start
jump
pushdb 0x10
next: pushdb 4
add
pushdb next
jump
div: push0
swap
rot
divnx: over
sub
dup
ltz
hopzi divdn
swap
inc
swap
hopi divnx
divdn: drop
drop
ret
fib: dup
retz
dtor
push0
pushdb 1
fiter: over
add
swap
repeati fiter
drop
ret
strlen: push0
swap
dup
fetchdb
+1
View File
@@ -0,0 +1 @@
  <
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1" encoding="UTF-8"?>
<!DOCTYPE gowin-fpga-project>
<Project>
<Template>FPGA</Template>
<Version>5</Version>
<Device name="GW2AR-18C" pn="GW2AR-LV18QN88C8/I7">gw2ar18c-000</Device>
<FileList>
<File path="/Users/car/Projects/hope/alu.v" type="file.verilog" enable="1"/>
<File path="/Users/car/Projects/hope/cpu.v" type="file.verilog" enable="1"/>
<File path="/Users/car/Projects/hope/register_file.v" type="file.verilog" enable="1"/>
<File path="/Users/car/Projects/hope/sequencer.v" type="file.verilog" enable="1"/>
<File path="/Users/car/Projects/hope/sram_srom.v" type="file.verilog" enable="1"/>
<File path="/Users/car/Projects/hope/tangnano20k.cst" type="file.cst" enable="1"/>
<File path="/Users/car/Projects/hope/tangnano20k.sdc" type="file.sdc" enable="1"/>
</FileList>
</Project>
+27
View File
@@ -0,0 +1,27 @@
<?xml version="1" encoding="UTF-8"?>
<!DOCTYPE ProjectUserData>
<UserConfig>
<Version>1.0</Version>
<FlowState>
<Process ID="Synthesis" State="2"/>
<Process ID="Pnr" State="2"/>
<Process ID="Gao" State="2"/>
<Process ID="Rtl_Gao" State="2"/>
<Process ID="Gvio" State="0"/>
<Process ID="Place" State="2"/>
</FlowState>
<ResultFileList>
<ResultFile ResultFileType="RES.netlist" ResultFilePath="impl/gwsynthesis/hope.vg"/>
<ResultFile ResultFileType="RES.pnr.bitstream" ResultFilePath="impl/pnr/hope.fs"/>
<ResultFile ResultFileType="RES.pnr.pin.rpt" ResultFilePath="impl/pnr/hope.pin.html"/>
<ResultFile ResultFileType="RES.pnr.posp.bin" ResultFilePath="impl/pnr/hope.db"/>
<ResultFile ResultFileType="RES.pnr.pwr.rpt" ResultFilePath="impl/pnr/hope.power.html"/>
<ResultFile ResultFileType="RES.pnr.report" ResultFilePath="impl/pnr/hope.rpt.html"/>
<ResultFile ResultFileType="RES.pnr.timing.paths" ResultFilePath="impl/pnr/hope.timing_paths"/>
<ResultFile ResultFileType="RES.pnr.timing.rpt" ResultFilePath="impl/pnr/hope.tr.html"/>
<ResultFile ResultFileType="RES.syn.report" ResultFilePath="impl/gwsynthesis/hope_syn.rpt.html"/>
<ResultFile ResultFileType="RES.syn.resource" ResultFilePath="impl/gwsynthesis/hope_syn_rsc.xml"/>
</ResultFileList>
<Ui>000000ff00000001fd0000000200000000000000a40000024ffc0200000001fc000000240000024f0000009b01000014fa000000000200000003fb00000030004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00440065007300690067006e0100000000ffffffff0000006400fffffffb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00500072006f00630065007300730100000000ffffffff0000006000fffffffb00000036004600700067006100500072006f006a006500630074002e00500061006e0065006c002e0048006900650072006100720063006800790100000000ffffffff0000008600ffffff00000003000007a3000000cdfc0100000001fc00000000000007a3000000a500fffffffa000000000100000002fb00000032004600700067006100500072006f006a006500630074002e00500061006e0065006c002e00470065006e006500720061006c0100000000ffffffff0000004c00fffffffb0000002e004600700067006100500072006f006a006500630074002e00500061006e0065006c002e004900730073007500650100000000ffffffff000000a500ffffff000006fe0000024f00000004000000040000000800000008fc000000010000000200000004000000220043006f00720065002e0054006f006f006c006200610072002e00460069006c00650100000000ffffffff0000000000000000000000220043006f00720065002e0054006f006f006c006200610072002e004500640069007401000000d1ffffffff0000000000000000000000240043006f00720065002e0054006f006f006c006200610072002e0054006f006f006c007301000001d2ffffffff0000000000000000000000280043006f00720065002e0054006f006f006c006200610072002e00500072006f006300650073007301000002bfffffffff0000000000000000</Ui>
<FpUi>312e30313131000000ff00000000fd0000000200000000000001000000015efc0200000001fc0000002c0000015e000000a101000014fa000000010200000002fb0000001c0044006f0063006b00650072002e00530075006d006d0061007200790100000000ffffffff0000008c00fffffffb0000001c0044006f0063006b00650072002e004e00650074006c0069007300740100000000ffffffff0000006000ffffff00000003000002f400000103fc0100000001fc00000000000002f4000001c100fffffffa00000000010000000bfb0000001c0044006f0063006b00650072002e004d0065007300730061006700650100000000ffffffff0000006200fffffffb0000002c0044006f0063006b00650072002e0049002f004f002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004a00fffffffb000000380044006f0063006b00650072002e005000720069006d00690074006900760065002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004a00fffffffb000000300044006f0063006b00650072002e00470072006f00750070002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004a00fffffffb000000360044006f0063006b00650072002e005200650073006f0075007200630065002e005200650073006500720076006100740069006f006e0100000000ffffffff0000004a00fffffffb000000380044006f0063006b00650072002e0043006c006f0063006b002e004e00650074002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004a00fffffffb000000420044006f0063006b00650072002e00470043004c004b002e005000720069006d00690074006900760065002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004a00fffffffb000000420044006f0063006b00650072002e00480043004c004b002e005000720069006d00690074006900760065002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004a00fffffffb000000440044006f0063006b00650072002e00470043004c004b0032002e005000720069006d00690074006900760065002e0043006f006e00730074007200610069006e007400730000000000ffffffff0000004a00fffffffb000000460044006f0063006b00650072002e00480043004c004b00350041002e005000720069006d00690074006900760065002e0043006f006e00730074007200610069006e007400730000000000ffffffff0000004a00fffffffb0000002e0044006f0063006b00650072002e0056007200650066002e0043006f006e00730074007200610069006e007400730100000000ffffffff0000004a00ffffff000001f30000015e00000004000000040000000800000008fc000000010000000200000001000000180054006f006f006c004200610072002e00460069006c00650100000000ffffffff0000000000000000</FpUi>
</UserConfig>
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE gowin-synthesis-project>
<Project>
<Version>beta</Version>
<Device id="GW2AR-18C" package="QFN88" speed="8" partNumber="GW2AR-LV18QN88C8/I7"/>
<FileList>
<File path="/Users/car/Projects/hope/alu.v" type="verilog"/>
<File path="/Users/car/Projects/hope/cpu.v" type="verilog"/>
<File path="/Users/car/Projects/hope/register_file.v" type="verilog"/>
<File path="/Users/car/Projects/hope/sequencer.v" type="verilog"/>
<File path="/Users/car/Projects/hope/sram_srom.v" type="verilog"/>
</FileList>
<OptionList>
<Option type="disable_insert_pad" value="0"/>
<Option type="global_freq" value="100.000"/>
<Option type="looplimit" value="2000"/>
<Option type="output_file" value="/Users/car/Projects/hope/hope/impl/gwsynthesis/hope.vg"/>
<Option type="print_all_synthesis_warning" value="0"/>
<Option type="ram_rw_check" value="0"/>
<Option type="vcc" value="1.0"/>
<Option type="verilog_language" value="verilog-2001"/>
<Option type="vhdl_language" value="vhdl-1993"/>
</OptionList>
</Project>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,86 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Hierarchy Module Resource</title>
<style type="text/css">
body { font-family: Verdana, Arial, sans-serif; font-size: 14px; }
div#main_wrapper{ width: 100%; }
h1 {text-align: center; }
h1 {margin-top: 36px; }
table, th, td { border: 1px solid #aaa; }
table { border-collapse:collapse; margin-top: 10px; margin-bottom: 20px; width: 100%; }
th, td { align = "center"; padding: 5px 2px 5px 5px; }
th { color: #fff; font-weight: bold; background-color: #0084ff; }
table td.label { width: 20%; white-space: nowrap; min-width: 20px; background-color: #dee8f4; }
</style>
</head>
<body>
<div id="main_wrapper">
<div id="content">
<h1>Hierarchy Module Resource</h1>
<table>
<tr>
<th class="label">MODULE NAME</th>
<th class="label">REG NUMBER</th>
<th class="label">ALU NUMBER</th>
<th class="label">LUT NUMBER</th>
<th class="label">DSP NUMBER</th>
<th class="label">BSRAM NUMBER</th>
<th class="label">SSRAM NUMBER</th>
<th class="label">ROM16 NUMBER</th>
</tr>
<tr>
<td class="label">cpu (/Users/car/Projects/hope/cpu.v)</td>
<td align = "center">7</td>
<td align = "center">-</td>
<td align = "center">60</td>
<td align = "center">-</td>
<td align = "center">1</td>
<td align = "center">-</td>
<td align = "center">-</td>
</tr>
<td class="label">&nbsp&nbsp&nbsp&nbsp|--register_file_inst
(/Users/car/Projects/hope/cpu.v)</td>
<td align = "center">102</td>
<td align = "center">-</td>
<td align = "center">285</td>
<td align = "center">-</td>
<td align = "center">-</td>
<td align = "center">12</td>
<td align = "center">-</td>
</tr>
<td class="label">&nbsp&nbsp&nbsp&nbsp|--alu_inst
(/Users/car/Projects/hope/cpu.v)</td>
<td align = "center">-</td>
<td align = "center">32</td>
<td align = "center">585</td>
<td align = "center">1</td>
<td align = "center">-</td>
<td align = "center">-</td>
<td align = "center">-</td>
</tr>
<td class="label">&nbsp&nbsp&nbsp&nbsp|--sequencer_inst
(/Users/car/Projects/hope/cpu.v)</td>
<td align = "center">9</td>
<td align = "center">-</td>
<td align = "center">90</td>
<td align = "center">-</td>
<td align = "center">-</td>
<td align = "center">-</td>
<td align = "center">-</td>
</tr>
<td class="label">&nbsp&nbsp&nbsp&nbsp|--sram_srom_inst
(/Users/car/Projects/hope/cpu.v)</td>
<td align = "center">24</td>
<td align = "center">-</td>
<td align = "center">71</td>
<td align = "center">-</td>
<td align = "center">8</td>
<td align = "center">-</td>
<td align = "center">-</td>
</tr>
</table>
</div><!-- content -->
</div><!-- main_wrapper -->
</body>
</html>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Module name="cpu" Register="7" Lut="60" Bsram="1" T_Register="142(7)" T_Alu="32(0)" T_Lut="1091(60)" T_MULT36X36="1(0)" T_Bsram="9(1)" T_Ssram="12(0)">
<SubModule name="register_file_inst" Register="102" Lut="285" Ssram="12" T_Register="102(102)" T_Lut="285(285)" T_Ssram="12(12)"/>
<SubModule name="alu_inst" Alu="32" Lut="585" MULT36X36="1" T_Alu="32(32)" T_Lut="585(585)" T_MULT36X36="1(1)"/>
<SubModule name="sequencer_inst" Register="9" Lut="90" T_Register="9(9)" T_Lut="90(90)"/>
<SubModule name="sram_srom_inst" Register="24" Lut="71" Bsram="8" T_Register="24(24)" T_Lut="71(71)" T_Bsram="8(8)"/>
</Module>
+1
View File
@@ -0,0 +1 @@
syn_ide_mode=true
+18
View File
@@ -0,0 +1,18 @@
-d /Users/car/Projects/hope/hope/impl/gwsynthesis/hope.vg
-p GW2AR-18C-QFN88-8
-pn GW2AR-LV18QN88C8/I7
-cst /Users/car/Projects/hope/tangnano20k.cst
-cfg /Users/car/Projects/hope/hope/impl/pnr/device.cfg
-sdc /Users/car/Projects/hope/tangnano20k.sdc
-bit
-tr
-ph
-timing
-cst_error
-convert_sdp32_36_to_sdp16_18
-place_option 0
-route_option 0
-clock_route_order 0
-correct_hold 1
-route_maxfan 23
-global_freq 100.000
+22
View File
@@ -0,0 +1,22 @@
set JTAG regular_io = false
set SSPI regular_io = false
set MSPI regular_io = false
set READY regular_io = false
set DONE regular_io = false
set I2C regular_io = false
set RECONFIG_N regular_io = false
set CRC_check = true
set compress = false
set encryption = false
set security_bit_enable = true
set bsram_init_fuse_print = true
set background_programming = off
set secure_mode = false
set program_done_bypass = false
set wake_up = 0
set format = binary
set power_on_reset_monitor = true
set multiboot_spi_flash_address = 0x00000000
set vccx = 3.3
set vcc = 1.0
set unused_pin = default
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+2146
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+298
View File
@@ -0,0 +1,298 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//ENhttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Power Analysis Report</title>
<style type="text/css">
body { font-family: Verdana, Arial, sans-serif; font-size: 12px; }
div#main_wrapper { width: 100%; }
div#content { margin-left: 350px; margin-right: 30px; }
div#catalog_wrapper {position: fixed; top: 30px; width: 350px; float: left; }
div#catalog ul { list-style-type: none; }
div#catalog li { text-align: left; list-style-type:circle; color: #0084ff; margin-top: 3px; margin-bottom: 3px; }
div#catalog a { display:inline-block; text-decoration: none; color: #0084ff; font-weight: bold; padding: 3px; }
div#catalog a:visited { color: #0084ff; }
div#catalog a:hover { color: #fff; background: #0084ff; }
hr { margin-top: 30px; margin-bottom: 30px; }
h1, h3 { text-align: center; }
h1 {margin-top: 50px; }
table, th, td {white-space:pre; border: 1px solid #aaa; }
table { border-collapse:collapse; margin-top: 10px; margin-bottom: 20px; width: 100%; }
th, td { padding: 5px 5px 5px 5px; }
th { color: #fff; font-weight: bold; background-color: #0084ff; }
table.summary_table td.label { width: 24%; min-width: 200px; background-color: #dee8f4; }
table.thermal_table td.label { width: 24%; min-width: 200px; background-color: #dee8f4; }
table.Configure_table td.label { width: 24%; min-width: 200px; background-color: #dee8f4; }
table.detail_table th.label { min-width: 8%; width: 8%; }
</style>
</head>
<body>
<div id="main_wrapper">
<div id="catalog_wrapper">
<div id="catalog">
<ul>
<li><a href="#Message" style=" font-size: 16px;">Power Messages</a>
<ul>
<li><a href="#Configure_Info" style=" font-size: 14px;">Configure Information</a></li>
</ul>
</li>
<li><a href="#Summary" style=" font-size: 16px;">Power Summary</a>
<ul>
<li><a href="#Power_Info" style=" font-size: 14px;">Power Information</a></li>
<li><a href="#Thermal_Info" style=" font-size: 14px;">Thermal Information</a></li>
<li><a href="#Supply_Summary" style=" font-size: 14px;">Supply Information</a></li>
</ul>
</li>
<li><a href="#Detail" style=" font-size: 16px;">Power Details</a>
<ul>
<li><a href="#By_Block_Type" style=" font-size: 14px;">Power By Block Type</a></li>
<li><a href="#By_Hierarchy" style=" font-size: 14px;">Power By Hierarchy</a></li>
<li><a href="#By_Clock_Domain" style=" font-size: 14px;">Power By Clock Domain</a></li>
</ul>
</li>
</ul>
</div><!-- catalog -->
</div><!-- catalog_wrapper -->
<div id="content">
<h1><a name="Message">Power Messages</a></h1>
<table class="summary_table">
<tr>
<td class="label">Report Title</td>
<td>Power Analysis Report</td>
</tr>
<tr>
<td class="label">Design File</td>
<td>/Users/car/Projects/hope/hope/impl/gwsynthesis/hope.vg</td>
</tr>
<tr>
<td class="label">Physical Constraints File</td>
<td>/Users/car/Projects/hope/tangnano20k.cst</td>
</tr>
<tr>
<td class="label">Timing Constraints File</td>
<td>/Users/car/Projects/hope/tangnano20k.sdc</td>
</tr>
<tr>
<td class="label">Tool Version</td>
<td>V1.9.11.03 Education</td>
</tr>
<tr>
<td class="label">Part Number</td>
<td>GW2AR-LV18QN88C8/I7</td>
</tr>
<tr>
<td class="label">Device</td>
<td>GW2AR-18</td>
</tr>
<tr>
<td class="label">Device Version</td>
<td>C</td>
</tr>
<tr>
<td class="label">Created Time</td>
<td>Fri Feb 20 01:45:30 2026
</td>
</tr>
<tr>
<td class="label">Legal Announcement</td>
<td>Copyright (C)2014-2025 Gowin Semiconductor Corporation. All rights reserved.</td>
</tr>
</table>
<h2><a name="Configure_Info">Configure Information:</a></h2>
<table class="summary_table">
<tr>
<td class="label">Grade</td>
<td>Commercial</td>
</tr>
<tr>
<td class="label">Process</td>
<td>Typical</td>
</tr>
<tr>
<td class="label">Ambient Temperature</td>
<td>25.000
</tr>
<tr>
<td class="label">Use Custom Theta JA</td>
<td>false</td>
</tr>
<tr>
<td class="label">Heat Sink</td>
<td>None</td>
</tr>
<tr>
<td class="label">Air Flow</td>
<td>LFM_0</td>
</tr>
<tr>
<td class="label">Use Custom Theta SA</td>
<td>false</td>
</tr>
<tr>
<td class="label">Board Thermal Model</td>
<td>None</td>
</tr>
<tr>
<td class="label">Use Custom Theta JB</td>
<td>false</td>
</tr>
<tr>
<td class="label">Related Vcd File</td>
<td></td>
</tr>
<tr>
<td class="label">Related Saif File</td>
<td></td>
</tr>
<tr>
<td class="label">Filter Glitches</td>
<td>false</td>
</tr>
<tr>
<td class="label">Default IO Toggle Rate</td>
<td>0.125</td>
</tr>
<tr>
<td class="label">Default Remain Toggle Rate</td>
<td>0.125</td>
</tr>
</table>
<h1><a name="Summary">Power Summary</a></h1>
<h2><a name="Power_Info">Power Information:</a></h2>
<table class="summary_table">
<tr>
<td class="label">Total Power (mW)</td>
<td>128.147</td>
</tr>
<tr>
<td class="label">Quiescent Power (mW)</td>
<td>122.800</td>
</tr>
<tr>
<td class="label">Dynamic Power (mW)</td>
<td>5.347</td>
</tr>
</table>
<h2><a name="Thermal_Info">Thermal Information:</a></h2>
<table class="summary_table">
<tr>
<td class="label">Junction Temperature</td>
<td>28.824</td>
</tr>
<tr>
<td class="label">Theta JA</td>
<td>29.840</td>
</tr>
<tr>
<td class="label">Max Allowed Ambient Temperature</td>
<td>81.176</td>
</tr>
</table>
<h2><a name="Supply_Summary">Supply Information:</a></h2>
<table class="summary_table">
<tr>
<th class="label">Voltage Source</th>
<th class="label">Voltage</th>
<th class="label">Dynamic Current(mA)</th>
<th class="label">Quiescent Current(mA)</th>
<th class="label">Power(mW)</th>
</tr>
<tr>
<td>VCC</td>
<td>1.000</td>
<td>3.582</td>
<td>70.000</td>
<td>73.582</td>
</tr>
<tr>
<td>VCCX</td>
<td>3.300</td>
<td>0.267</td>
<td>15.000</td>
<td>50.383</td>
</tr>
<tr>
<td>VCCIO33</td>
<td>3.300</td>
<td>0.267</td>
<td>1.000</td>
<td>4.183</td>
</tr>
</table>
<h1><a name="Detail">Power Details</a></h1>
<h2><a name="By_Block_Type">Power By Block Type:</a></h2>
<table class="detail_table">
<tr>
<th class="label">Block Type</th>
<th class="label">Total Power(mW)</th>
<th class="label">Static Power(mW)</th>
<th class="label">Average Toggle Rate(millions of transitions/sec)</th>
</tr>
<tr>
<td>Logic</td>
<td>0.391</td>
<td>NA</td>
<td>3.370</td>
</tr>
<tr>
<td>IO</td>
<td>6.901
<td>4.869
<td>5.625
</tr>
<tr>
<td>BSRAM</td>
<td>2.918
<td>NA</td>
<td>NA</td>
</tr>
</table>
<h2><a name="By_Hierarchy">Power By Hierarchy:</a></h2>
<table class="detail_table">
<tr>
<th class="label">Hierarchy Entity</th>
<th class="label">Total Power(mW)</th>
<th class="label">Block Dynamic Power(mW)</th>
</tr>
<tr>
<td>cpu</td>
<td>3.309</td>
<td>3.309(2.901)</td>
<tr>
<td>cpu/alu_inst/</td>
<td>0.223</td>
<td>0.223(0.000)</td>
<tr>
<td>cpu/register_file_inst/</td>
<td>0.103</td>
<td>0.103(0.000)</td>
<tr>
<td>cpu/sequencer_inst/</td>
<td>0.025</td>
<td>0.025(0.000)</td>
<tr>
<td>cpu/sram_srom_inst/</td>
<td>2.549</td>
<td>2.549(0.000)</td>
</table>
<h2><a name="By_Clock_Domain">Power By Clock Domain:</a></h2>
<table class="detail_table">
<tr>
<th class="label">Clock Domain</th>
<th class="label">Clock Frequency(Mhz)</th>
<th class="label">Total Dynamic Power(mW)</th>
</tr>
<tr>
<td>i_clk</td>
<td>26.998</td>
<td>3.315</td>
</tr>
<tr>
<td>NO CLOCK DOMAIN</td>
<td>0.000</td>
<td>0.000</td>
</tr>
</table>
</div><!-- content -->
</div><!-- main_wrapper -->
</body>
</html>
File diff suppressed because it is too large Load Diff
+255
View File
@@ -0,0 +1,255 @@
//Copyright (C)2014-2025 Gowin Semiconductor Corporation.
//All rights reserved.
1. PnR Messages
<Report Title>: PnR Report
<Design File>: /Users/car/Projects/hope/hope/impl/gwsynthesis/hope.vg
<Physical Constraints File>: /Users/car/Projects/hope/tangnano20k.cst
<Timing Constraints File>: /Users/car/Projects/hope/tangnano20k.sdc
<Tool Version>: V1.9.11.03 Education
<Part Number>: GW2AR-LV18QN88C8/I7
<Device>: GW2AR-18
<Device Version>: C
<Created Time>:Fri Feb 20 01:45:30 2026
2. PnR Details
Running placement:
Placement Phase 0: CPU time = 0h 0m 0.029s, Elapsed time = 0h 0m 0.026s
Placement Phase 1: CPU time = 0h 0m 0.092s, Elapsed time = 0h 0m 0.087s
Placement Phase 2: CPU time = 0h 0m 0.057s, Elapsed time = 0h 0m 0.054s
Placement Phase 3: CPU time = 0h 0m 0.305s, Elapsed time = 0h 0m 0.299s
Total Placement: CPU time = 0h 0m 0.483s, Elapsed time = 0h 0m 0.466s
Running routing:
Routing Phase 0: CPU time = 0h 0m 0s, Elapsed time = 0h 0m 0s
Routing Phase 1: CPU time = 0h 0m 0.049s, Elapsed time = 0h 0m 0.05s
Routing Phase 2: CPU time = 0h 0m 0.357s, Elapsed time = 0h 0m 0.317s
Routing Phase 3: CPU time = 0h 0m 0s, Elapsed time = 0h 0m 0s
Total Routing: CPU time = 0h 0m 0.406s, Elapsed time = 0h 0m 0.367s
Generate output files:
CPU time = 0h 0m 0.987s, Elapsed time = 0h 0m 0.958s
Total Time and Memory Usage: CPU time = 0h 0m 2s, Elapsed time = 0h 0m 2s, Peak memory usage = 1416MB
3. Resource Usage Summary
--------------------------------------------------------------------------------
Resources | Usage | Utilization
--------------------------------------------------------------------------------
Logic | 1196/20736 | 6%
--LUT,ALU,ROM16 | 1124(1091 LUT, 33 ALU, 0 ROM16) | -
--SSRAM(RAM16) | 12 | -
Register | 142/15750 | <1%
--Logic Register as Latch | 0/15552 | 0%
--Logic Register as FF | 136/15552 | <1%
--I/O Register as Latch | 0/198 | 0%
--I/O Register as FF | 6/198 | 4%
CLS | 702/10368 | 7%
I/O Port | 10/66 | 16%
I/O Buf | 9 | -
--Input Buf | 2 | -
--Output Buf | 7 | -
--Inout Buf | 0 | -
BSRAM | 9/46 | 20%
--SP | 8
--pROM | 1
DSP | 2/24 | 9%
--MULT36X36 | 1
================================================================================
4. I/O Bank Usage Summary
--------------------------------------
I/O Bank | Usage | Utilization
--------------------------------------
bank 0 | 0/8 | 0%
bank 1 | 2/9 | 23%
bank 2 | 0/4 | 0%
bank 3 | 1/17 | 6%
bank 4 | 0/8 | 0%
bank 5 | 0/10 | 0%
bank 6 | 6/9 | 67%
bank 7 | 1/1 | 100%
======================================
5. Clock Resource Usage Summary
------------------------------------------
Clock Resource| Usage | Utilization
------------------------------------------
PRIMARY | 1/8 | 13%
LW | 1/8 | 13%
GCLK_PIN | 0/5 | 0%
==========================================
6. Global Clock Signals
-------------------------------------------
Signal | Global Clock | Location
-------------------------------------------
i_clk_d | PRIMARY | TR BR BL
addr_registers[0]_ER_init| LW | -
===========================================
7. Pinout by Port Name
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Port Name | Diff Pair | Loc./Bank | Constraint | Dir. | Site | CFG | IO Type | Drive | Pull Mode | PCI Clamp | Hysteresis | Open Drain | Vref | Single Resistor | Diff Resistor | BankVccio
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
i_clk | - | 4/7 | Y | in | IOL7[A] | LPLL1_T_in | LVCMOS33 | NA | UP | ON | NONE | NA | NA | OFF | NA | 3.3
i_rst_n | - | 88/3 | Y | in | IOR30[A] | MODE0 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | OFF | NA | 3.3
i_uart_rx | - | 70/1 | Y | in | IOT44[B] | - | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
o_uart_tx | - | 69/1 | Y | out | IOT50[A] | - | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | NA | NA | 3.3
o_led[0] | - | 15/6 | Y | out | IOL47[A] | LPLL2_T_fb | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
o_led[1] | - | 16/6 | Y | out | IOL47[B] | LPLL2_C_fb | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
o_led[2] | - | 17/6 | Y | out | IOL49[A] | - | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
o_led[3] | - | 18/6 | Y | out | IOL49[B] | - | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
o_led[4] | - | 19/6 | Y | out | IOL51[A] | - | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
o_led[5] | - | 20/6 | Y | out | IOL51[B] | - | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
==================================================================================================================================================================================================================
8. All Package Pins
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Loc./Bank| Signal | Dir. | Site | CFG | IO Type | Drive | Pull Mode | PCI Clamp | Hysteresis | Open Drain | Vref | Single Resistor | Diff Resistor | Bank Vccio
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
86/0 | - | in | IOT4[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
85/0 | - | in | IOT4[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
84/0 | - | in | IOT6[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
83/0 | - | in | IOT6[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
82/0 | - | in | IOT17[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
81/0 | - | in | IOT17[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
80/0 | - | in | IOT27[A] | GCLKT_0 | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
79/0 | - | in | IOT27[B] | GCLKC_0 | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
77/1 | - | in | IOT30[A] | GCLKT_1 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
76/1 | - | in | IOT30[B] | GCLKC_1 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
75/1 | - | in | IOT34[A] | - | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
74/1 | - | in | IOT34[B] | - | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
73/1 | - | in | IOT40[A] | - | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
72/1 | - | in | IOT40[B] | - | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
71/1 | - | in | IOT44[A] | - | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
70/1 | i_uart_rx | in | IOT44[B] | - | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
69/1 | o_uart_tx | out | IOT50[A] | - | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | NA | NA | 3.3
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
25/5 | - | in | IOB6[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
26/5 | - | in | IOB6[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
27/5 | - | in | IOB8[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
28/5 | - | in | IOB8[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
29/5 | - | in | IOB14[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
30/5 | - | in | IOB14[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
31/5 | - | in | IOB18[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
32/5 | - | in | IOB18[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
33/5 | - | in | IOB24[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
34/5 | - | in | IOB24[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
35/4 | - | in | IOB30[A] | GCLKT_4 | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
36/4 | - | in | IOB30[B] | GCLKC_4 | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
37/4 | - | in | IOB34[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
38/4 | - | in | IOB34[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
39/4 | - | in | IOB40[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
40/4 | - | in | IOB40[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
42/4 | - | in | IOB42[B] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
41/4 | - | in | IOB43[A] | - | LVCMOS18 | NA | UP | ON | NONE | NA | NA | NA | NA | 1.8
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
p1/7 | - | in | IOL3[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p2/7 | - | in | IOL3[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
4/7 | i_clk | in | IOL7[A] | LPLL1_T_in | LVCMOS33 | NA | UP | ON | NONE | NA | NA | OFF | NA | 3.3
p5/7 | - | in | IOL8[A] | LPLL1_T_fb | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p6/7 | - | in | IOL8[B] | LPLL1_C_fb | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p7/7 | - | in | IOL9[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p8/7 | - | in | IOL9[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p11/7 | - | in | IOL11[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p12/7 | - | in | IOL11[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p14/7 | - | in | IOL12[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p19/7 | - | in | IOL12[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p18/7 | - | in | IOL13[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p21/7 | - | in | IOL13[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p20/7 | - | in | IOL14[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p22/7 | - | in | IOL14[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p23/7 | - | in | IOL15[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p24/7 | - | in | IOL15[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p26/7 | - | in | IOL16[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p28/7 | - | in | IOL16[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p25/7 | - | in | IOL17[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p27/7 | - | in | IOL17[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p29/7 | - | in | IOL18[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p31/7 | - | in | IOL18[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p32/7 | - | in | IOL20[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
10/6 | - | in | IOL29[A] | GCLKT_6 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
11/6 | - | in | IOL29[B] | GCLKC_6 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
p35/6 | - | in | IOL30[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p36/6 | - | in | IOL30[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p37/6 | - | in | IOL35[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p38/6 | - | in | IOL35[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p41/6 | - | in | IOL39[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p42/6 | - | in | IOL39[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
13/6 | - | in | IOL45[A] | LPLL2_T_in | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
15/6 | o_led[0] | out | IOL47[A] | LPLL2_T_fb | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
16/6 | o_led[1] | out | IOL47[B] | LPLL2_C_fb | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
17/6 | o_led[2] | out | IOL49[A] | - | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
18/6 | o_led[3] | out | IOL49[B] | - | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
19/6 | o_led[4] | out | IOL51[A] | - | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
20/6 | o_led[5] | out | IOL51[B] | - | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | OFF | NA | 3.3
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
p89/2 | - | in | IOR3[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p88/2 | - | in | IOR3[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p85/2 | - | in | IOR4[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p84/2 | - | in | IOR5[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p82/2 | - | in | IOR5[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p83/2 | - | in | IOR6[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p79/2 | - | in | IOR9[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p78/2 | - | in | IOR9[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p76/2 | - | in | IOR11[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p73/2 | - | in | IOR11[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p70/2 | - | in | IOR12[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p68/2 | - | in | IOR12[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p69/2 | - | in | IOR13[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p66/2 | - | in | IOR13[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p67/2 | - | in | IOR14[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p65/2 | - | in | IOR14[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p64/2 | - | in | IOR15[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p61/2 | - | in | IOR15[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p58/2 | - | in | IOR16[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p55/2 | - | in | IOR16[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p59/2 | - | in | IOR17[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p54/2 | - | in | IOR17[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p53/2 | - | in | IOR18[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p52/2 | - | in | IOR18[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
8/2 | - | out | IOR25[A] | TDO | LVCMOS33 | 8 | UP | NA | NA | OFF | NA | NA | NA | 3.3
5/2 | - | in | IOR25[B] | TMS | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
6/2 | - | in | IOR26[A] | TCK | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
7/2 | - | in | IOR26[B] | TDI | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
63/3 | - | in | IOR29[A] | GCLKT_3 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
88/3 | i_rst_n | in | IOR30[A] | MODE0 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | OFF | NA | 3.3
87/3 | - | in | IOR30[B] | MODE1 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
9/3 | - | in | IOR31[B] | RECONFIG_N | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
62/3 | - | in | IOR33[A] | MI/D7 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
61/3 | - | in | IOR33[B] | MO/D6 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
60/3 | - | in | IOR34[A] | MCS_N/D5 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
59/3 | - | in | IOR34[B] | MCLK/D4 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
57/3 | - | in | IOR35[A] | FASTRD_N/D3 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
56/3 | - | in | IOR36[A] | SO/D1 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
55/3 | - | in | IOR36[B] | SSPI_CS_N/D0 | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
54/3 | - | in | IOR38[A] | DIN/CLKHOLD_N | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
53/3 | - | in | IOR38[B] | DOUT/WE_N | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
52/3 | - | in | IOR39[A] | SCLK | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
p49/3 | - | in | IOR44[A] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
p48/3 | - | in | IOR44[B] | - | LVCMOS33 | - | UP | - | - | - | - | - | - | -
51/3 | - | in | IOR45[A] | RPLL2_T_in | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
49/3 | - | in | IOR49[A] | - | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
48/3 | - | in | IOR49[B] | - | LVCMOS33 | NA | UP | ON | NONE | NA | NA | NA | NA | 3.3
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
=======================================================================================================================================================================================
File diff suppressed because it is too large Load Diff
+10
View File
@@ -0,0 +1,10 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Timing Analysis Report</title>
</head>
<frameset cols="20%, 80%">
<frame src="hope_tr_cata.html" name="cataFrame" />
<frame src="hope_tr_content.html" name="mainFrame"/>
</frameset>
</html>
+132
View File
@@ -0,0 +1,132 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Timing Report Navigation</title>
<style type="text/css">
@import url(../temp/style.css);
body { font-family: Verdana, Arial, sans-serif; font-size: 12px; }
div#catalog_wrapper { width: 100%; }
div#catalog ul { list-style: none; margin-left: -15px; }
div#catalog ul li { margin: 3px 0 3px 0; text-align: left; color: #0084ff; white-space: nowrap; word-break: keep-all; }
div#catalog a { display:inline-block; text-decoration: none; color: #0084ff; font-weight: bold; padding: 4px; margin: 0 0 0 0; }
div#catalog a:visited { color: #0084ff; }
div#catalog a:hover { color: #fff; background: #0084ff; }
div.triangle_fake, div.triangle { display: inline-block; cursor: pointer; width: 8px; height: 0; border-top: 5px solid transparent; border-bottom: 5px solid transparent; }
div.triangle_fake { border-left: 5px solid transparent; }
div.triangle { border-left: 5px solid #0084ff; }
div.triangle:hover { border-left-color: #000; }
</style>
<script>
function onClick(obj){var childs=obj.parentNode.childNodes;for(var i=0;i<childs.length;i++){if(childs[i].tagName=="UL"){if(childs[i].style.display=="none"){childs[i].style.display="block"}else{childs[i].style.display="none"}}}};
</script>
</head>
<body>
<div id="catalog_wrapper">
<div id="catalog">
<ul>
<!-- messages begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Message" target="mainFrame" style=" font-size: 16px;">Timing Messages</a></li>
<!-- messages end-->
<!-- summaries begin-->
<li><div class="triangle" onclick="onClick(this)"></div><a href="hope_tr_content.html#Summary" style=" font-size: 16px;" target="mainFrame">Timing Summaries</a>
<ul>
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#STA_Tool_Run_Summary" style=" font-size: 14px;" target="mainFrame">STA Tool Run Summary</a></li>
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Clock_Report" style=" font-size: 14px;" target="mainFrame">Clock Summary</a></li>
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Max_Frequency_Report" style=" font-size: 14px;" target="mainFrame">Max Frequency Summary</a></li>
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Total_Negative_Slack_Report" style=" font-size: 14px;" target="mainFrame">Total Negative Slack Summary</a></li>
</ul>
</li>
<!-- summaries end-->
<!-- details begin-->
<li><div class="triangle" onclick="onClick(this)"></div><a href="hope_tr_content.html#Detail" style=" font-size: 16px;" target="mainFrame">Timing Details</a>
<ul>
<!--All_Path_Slack_Table begin-->
<li><div class="triangle" onclick="onClick(this)"></div><a href="hope_tr_content.html#All_Path_Slack_Table" style=" font-size: 14px;" target="mainFrame">Path Slacks Table</a>
<ul>
<!--Setup_Slack_Table begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Setup_Slack_Table" style=" font-size: 13px;" target="mainFrame">Setup Paths Table</a>
</li>
<!--Setup_Slack_Table end-->
<!--Hold_Slack_Table begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Hold_Slack_Table" style=" font-size: 13px;" target="mainFrame">Hold Paths Table</a>
</li>
<!--Hold_Slack_Table end-->
<!--Recovery_Slack_Table begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Recovery_Slack_Table" style=" font-size: 13px;" target="mainFrame">Recovery Paths Table</a>
</li>
<!--Recovery_Slack_Table end-->
<!--Removal_Slack_Table begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Removal_Slack_Table" style=" font-size: 13px;" target="mainFrame">Removal Paths Table</a>
</li>
<!--Removal_Slack_Table end-->
</ul>
</li><!--All_Path_Slack_Table end-->
<!--MIN_PULSE_WIDTH_TABLE begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#MIN_PULSE_WIDTH_TABLE" style=" font-size: 14px;" target="mainFrame">Minimum Pulse Width Table</a>
</li>
<!--MIN_PULSE_WIDTH_TABLE end-->
<!--Timing_Report_by_Analysis_Type begin-->
<li><div class="triangle" onclick="onClick(this)"></div><a href="hope_tr_content.html#Timing_Report_by_Analysis_Type" style=" font-size: 14px;" target="mainFrame">Timing Report By Analysis Type</a>
<ul>
<!--Setup_Analysis begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Setup_Analysis" style=" font-size: 13px;" target="mainFrame">Setup Analysis Report</a>
</li>
<!--Setup_Analysis end-->
<!--Hold_Analysis begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Hold_Analysis" style=" font-size: 13px;" target="mainFrame">Hold Analysis Report</a>
</li>
<!--Hold_Analysis end-->
<!--Recovery_Analysis begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Recovery_Analysis" style=" font-size: 13px;" target="mainFrame">Recovery Analysis Report</a>
</li>
<!--Recovery_Analysis end-->
<!--Removal_Analysis begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Removal_Analysis" style=" font-size: 13px;" target="mainFrame">Removal Analysis Report</a>
</li>
<!--Removal_Analysis end-->
</ul>
</li>
<!--Timing_Report_by_Analysis_Type end-->
<!--Minimum_Pulse_Width_Report begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Minimum_Pulse_Width_Report" style=" font-size: 14px;" target="mainFrame">Minimum Pulse Width Report</a>
</li>
<!--Minimum_Pulse_Width_Report end-->
<!--High_Fanout_Nets_Report begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#High_Fanout_Nets_Report" style=" font-size: 14px;" target="mainFrame">High Fanout Nets Report</a></li>
<!--High_Fanout_Nets_Report end-->
<!--Route_Congestions_Report begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Route_Congestions_Report" style=" font-size: 14px;" target="mainFrame">Route Congestions Report</a></li>
<!--Route_Congestions_Report end-->
<!--Timing_Exceptions_Report begin-->
<li><div class="triangle" onclick="onClick(this)"></div><a href="hope_tr_content.html#Timing_Exceptions_Report" style=" font-size: 14px;" target="mainFrame">Timing Exceptions Report</a>
<ul>
<!--Setup_Analysis_Exceptions begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Setup_Analysis_Exceptions" style=" font-size: 13px;" target="mainFrame">Setup Analysis Report</a>
</li>
<!--Setup_Analysis_Exceptions end-->
<!--Hold_Analysis_Exceptions begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Hold_Analysis_Exceptions" style=" font-size: 13px;" target="mainFrame">Hold Analysis Report</a>
</li>
<!--Hold_Analysis_Exceptions end-->
<!--Recovery_Analysis_Exceptions begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#Recovery_Analysis_Exceptions" style=" font-size: 13px;" target="mainFrame">Recovery Analysis Report</a>
</li>
<!--Recovery_Analysis_Exceptions end-->
<!--Removal_Analysis_Exceptions begin-->
<li><div class="triangle_fake" onclick="onClick(this)"></div><a href="hope_tr_content.html#Removal_Analysis_Exceptions" style=" font-size: 13px;" target="mainFrame">Removal Analysis Report</a>
</li>
<!--Removal_Analysis_Exceptions end-->
</ul>
</li>
<!--Timing_Exceptions_Report end-->
<!--SDC_Report begin-->
<li><div class="triangle_fake"></div><a href="hope_tr_content.html#SDC_Report" style=" font-size: 14px;" target="mainFrame">Timing Constraints Report</a></li>
<!--SDC_Report end-->
</ul>
</li>
<!-- details end-->
</ul>
</div><!-- catalog -->
</div><!-- catalog_wrapper -->
</body>
</html>
File diff suppressed because it is too large Load Diff
+44
View File
@@ -0,0 +1,44 @@
[
{
"InstFile" : "/Users/car/Projects/hope/cpu.v",
"InstLine" : 1,
"InstName" : "cpu",
"ModuleFile" : "/Users/car/Projects/hope/cpu.v",
"ModuleLine" : 1,
"ModuleName" : "cpu",
"SubInsts" : [
{
"InstFile" : "/Users/car/Projects/hope/cpu.v",
"InstLine" : 124,
"InstName" : "register_file_inst",
"ModuleFile" : "/Users/car/Projects/hope/register_file.v",
"ModuleLine" : 1,
"ModuleName" : "register_file"
},
{
"InstFile" : "/Users/car/Projects/hope/cpu.v",
"InstLine" : 142,
"InstName" : "alu_inst",
"ModuleFile" : "/Users/car/Projects/hope/alu.v",
"ModuleLine" : 1,
"ModuleName" : "alu"
},
{
"InstFile" : "/Users/car/Projects/hope/cpu.v",
"InstLine" : 149,
"InstName" : "sequencer_inst",
"ModuleFile" : "/Users/car/Projects/hope/sequencer.v",
"ModuleLine" : 1,
"ModuleName" : "sequencer"
},
{
"InstFile" : "/Users/car/Projects/hope/cpu.v",
"InstLine" : 158,
"InstName" : "sram_srom_inst",
"ModuleFile" : "/Users/car/Projects/hope/sram_srom.v",
"ModuleLine" : 1,
"ModuleName" : "sram_srom"
}
]
}
]
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
ISA:
+ (a b -- y) Addition
- (a b -- y) Subtraction
+12
View File
@@ -0,0 +1,12 @@
module mapper
(input [5:0] i_addr,
output [8:0] o_data);
reg [8:0] mapping_rom [63:0];
initial begin
$readmemh("/Users/car/Projects/hope/umap.hex", mapping_rom);
end
assign o_data = mapping_rom[i_addr];
endmodule
+49
View File
@@ -0,0 +1,49 @@
module register_file
(input i_clk,
input i_rst,
input i_halt,
input [2:0] i_rs1_addr,
input [1:0] i_rs2_addr,
input [1:0] i_rma_addr,
input [2:0] i_rd_addr,
input [31:0] i_rd_data,
input i_rd_we,
input i_mdr_we,
input [31:0] i_mdr_data,
input [8:0] i_imm,
output [31:0] o_rs1_data,
output [31:0] o_rs2_data,
output [23:0] o_rma_data,
output [31:0] o_mdr_data);
reg [23:0] addr_registers [0:3]; // PCP DSP RSP TMP
reg [31:0] data_registers [0:2]; // MDR TOS ACC (IMM)
integer i;
assign o_mdr_data = data_registers[0];
assign o_rma_data = addr_registers[i_rma_addr];
assign o_rs1_data = (i_rs1_addr != 3'b111) ? (i_rs1_addr[2] ? data_registers[i_rs1_addr[1:0]] : {8'd0, addr_registers[i_rs1_addr[1:0]]}) : i_imm;
assign o_rs2_data = (i_rs2_addr != 2'b11) ? data_registers[i_rs2_addr[1:0]] : i_imm;
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
for (i = 0; i < 4; i = i + 1) begin
addr_registers[i] <= 0;
if (i != 3) data_registers[i] <= 0;
end
end else begin
if (i_rd_we && !i_halt && i_rd_addr != 3'b111) begin
if (i_rd_addr != 3'd4 || !i_mdr_we) begin
if (i_rd_addr[2])
data_registers[i_rd_addr[1:0]] <= i_rd_data;
else
addr_registers[i_rd_addr[1:0]] <= i_rd_data[23:0];
end
end
if (i_mdr_we)
data_registers[0] <= i_mdr_data;
end
end
endmodule // register_file
Executable
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env python3
import sys
fin = open(sys.argv[1], "r")
fout = open(sys.argv[2], "w")
for line in fin.readlines():
line = line.strip()
w = [line[i:i+2] for i in range(0, len(line), 2)]
fout.write(f"{w[3]}{w[2]}{w[1]}{w[0]}\n")
fin.close()
fout.close()
+39
View File
@@ -0,0 +1,39 @@
module sequencer
(input i_clk,
input i_rst,
input [8:0] i_a,
input [1:0] i_op,
input i_cc,
input i_halt,
output [8:0] o_y);
wire [8:0] inc_pc;
wire [8:0] next_pc;
wire [8:0] next_ra;
reg [8:0] pc;
reg [8:0] ra;
assign inc_pc = pc + 1;
assign next_pc = (i_halt) ? pc :
(i_op[0] & i_cc) ? i_a :
(i_op[1] & ~i_op[0] & i_cc) ? ra :
inc_pc;
assign next_ra = (i_op == 2'b11 && !i_halt) ? inc_pc :
(i_op == 2'b10 && !i_halt) ? 0 :
ra;
assign o_y = next_pc;
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
pc <= 9'h1F8;
ra <= 0;
end else begin
pc <= next_pc;
ra <= next_ra;
end
end
endmodule
+206
View File
@@ -0,0 +1,206 @@
module sram_srom
(input i_clk,
input i_rst,
input i_dir,
input [1:0] i_act,
input [23:0] i_addr,
input [31:0] i_data,
output reg [31:0] o_data,
output o_we,
output reg o_stb);
(* ram_style = "block" *) reg [7:0] sram0 [4095:0];
(* ram_style = "block" *) reg [7:0] sram1 [4095:0];
(* ram_style = "block" *) reg [7:0] sram2 [4095:0];
(* ram_style = "block" *) reg [7:0] sram3 [4095:0];
(* ram_style = "block" *) reg [31:0] srom [4095:0];
wire use_ram;
wire use_rom;
wire [7:0] data0, data1, data2, data3;
wire [11:0] waddr;
reg wram0, wram1, wram2, wram3;
reg [7:0] wdata1, wdata2, wdata3;
reg [7:0] rdata0, rdata1, rdata2, rdata3;
reg [31:0] mdata;
reg waiter;
integer i;
assign data0 = i_data[7:0];
assign data1 = i_data[15:8];
assign data2 = i_data[23:16];
assign data3 = i_data[31:24];
assign waddr = i_addr[13:2];
assign use_ram = i_addr >= 24'h004000 && i_addr < 24'h008000;
assign use_rom = i_addr < 24'h004000;
//assign o_data = {rdata3, rdata2, rdata1, rdata0};
assign o_we = !i_dir && i_act != 2'b00;
initial begin
$readmemh("/Users/car/Projects/hope/srom.hex", srom);
end
always @(posedge i_clk, posedge i_rst) begin
if (i_rst)
o_stb <= 0;
else if (~o_stb)
o_stb <= (i_act != 2'b00);
else
o_stb <= 0;
end
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
rdata0 <= 8'd0;
rdata1 <= 8'd0;
rdata2 <= 8'd0;
rdata3 <= 8'd0;
mdata <= 32'd0;
end else begin
if (wram0) sram0[waddr] <= data0;
if (wram1) sram1[waddr] <= wdata1;
if (wram2) sram2[waddr] <= wdata2;
if (wram3) sram3[waddr] <= wdata3;
rdata0 <= sram0[waddr];
rdata1 <= sram1[waddr];
rdata2 <= sram2[waddr];
rdata3 <= sram3[waddr];
mdata <= srom[waddr];
end // else: !if(i_rst)
end
always @(*) begin
/*if (i_rst) begin
for (i = 0; i < 20; i = i + 1) begin
sram0[i] = 0;
sram1[i] = 0;
sram2[i] = 0;
sram3[i] = 0;
end
end
else */
if (i_dir && use_ram && i_act != 2'b00) begin
case (i_act)
2'b01: begin
/* write word */
{wram3, wram2, wram1, wram0} = 4'b1111;
{wdata3, wdata2, wdata1} = {data3, data2, data1};
end
2'b10: begin
/* write half-word */
{wdata3, wdata2, wdata1} = {data1, data0, data1};
if (i_addr[1]) begin
{wram3, wram2, wram1, wram0} = 4'b1100;
end else begin
{wram3, wram2, wram1, wram0} = 4'b0011;
end
end
2'b11: begin
/* write byte */
{wdata3, wdata2, wdata1} = {data0, data0, data0};
case (i_addr[1:0])
2'b00: begin
{wram3, wram2, wram1, wram0} = 4'b0001;
end
2'b01: begin
{wram3, wram2, wram1, wram0} = 4'b0010;
end
2'b10: begin
{wram3, wram2, wram1, wram0} = 4'b0100;
end
2'b11: begin
{wram3, wram2, wram1, wram0} = 4'b1000;
end
endcase // case (i_addr[1:0])
end // case: 2'b11
default: begin
{wram3, wram2, wram1, wram0} = 4'b0000;
{wdata3, wdata2, wdata1} = 24'd0;
end
endcase // case (i_act)
end else begin // if (i_dir && use_ram && i_act != 2'b00)
{wram3, wram2, wram1, wram0} = 4'b0000;
{wdata3, wdata2, wdata1} = {data0, data0, data0};
end
end // always @ (posedge i_clk, posedge i_rst)
always @(*) begin
if (!i_dir && use_ram) begin
/* SRAM */
case (i_act)
2'b00: begin
/* nop */
o_data = 32'd0;
end
2'b01: begin
/* read word */
o_data = {rdata3, rdata2, rdata1, rdata0};
end
2'b10: begin
/* read half-word */
o_data[15:0] = i_addr[1] ?
{rdata3, rdata2} :
{rdata1, rdata0};
o_data[31:16] = 16'd0;
end
2'b11: begin
/* read byte */
o_data[7:0] = (i_addr[1:0] == 2'b00) ? rdata0 :
(i_addr[1:0] == 2'b01) ? rdata1 :
(i_addr[1:0] == 2'b10) ? rdata2 :
rdata3;
o_data[31:8] = 24'd0;
end
endcase
end else if (!i_dir && use_rom) begin
case (i_act)
2'b00: begin
/* nop */
o_data = 32'd0;
end
2'b01: begin
/* read word */
o_data = mdata;
end
2'b10: begin
/* read half-word */
o_data = {16'd0, (i_addr[1] ? mdata[31:16] : mdata[15:0])};
end
2'b11: begin
/* read byte */
o_data = {24'd0, ((i_addr[1:0] == 2'b00) ? mdata[7:0] :
(i_addr[1:0] == 2'b01) ? mdata[15:8] :
(i_addr[1:0] == 2'b10) ? mdata[23:16] :
mdata[31:24])};
end
endcase
end else o_data = mdata; // if (use_rom)
end // always @ (posedge i_clk, posedge i_rst)
initial begin
// Simple test: PUSHB 0x42, infinite loop
//mem[0] = 8'h10; // PUSHB (opcode bits[7:3] = 2 → entry 2 → pushb)
//mem[1] = 8'h42; // immediate value
//mem[2] = 8'h10; // PUSHB again
//mem[3] = 8'h33; // different value
// After this, will fetch garbage and execute nop/fetch
end
endmodule
+8
View File
@@ -0,0 +1,8 @@
20
10
20
04
14
20
02
3c
+8
View File
@@ -0,0 +1,8 @@
8434088c
8c008c64
30123c01
8038fba0
098c088c
68108c74
048c108c
681a8c12
+8
View File
@@ -0,0 +1,8 @@
8c083484
648c008c
013c1230
a0fb3880
8c088c09
748c1068
8c108c04
128c1a68
+21
View File
@@ -0,0 +1,21 @@
IO_LOC "i_clk" 4; // 27 MHz
IO_LOC "i_rst_n" 88;
IO_LOC "o_led[0]" 15;
IO_LOC "o_led[1]" 16;
IO_LOC "o_led[2]" 17;
IO_LOC "o_led[3]" 18;
IO_LOC "o_led[4]" 19;
IO_LOC "o_led[5]" 20;
IO_LOC "o_uart_tx" 69;
IO_LOC "i_uart_rx" 70;
IO_PORT "i_rst_n" IO_TYPE=LVCMOS33;
IO_PORT "i_clk" IO_TYPE=LVCMOS33 PULL_MODE=UP;
IO_PORT "o_led[0]" IO_TYPE=LVCMOS33;
IO_PORT "o_led[1]" IO_TYPE=LVCMOS33;
IO_PORT "o_led[2]" IO_TYPE=LVCMOS33;
IO_PORT "o_led[3]" IO_TYPE=LVCMOS33;
IO_PORT "o_led[4]" IO_TYPE=LVCMOS33;
IO_PORT "o_led[5]" IO_TYPE=LVCMOS33;
IO_PORT "o_uart_tx" IO_TYPE=LVCMOS33;
IO_PORT "i_uart_rx" IO_TYPE=LVCMOS33;
+3
View File
@@ -0,0 +1,3 @@
create_clock -name i_clk -period 37.04 -waveform {0 18.518} [get_ports {i_clk}] -add
report_timing -hold -from_clock [get_clocks {i_clk}] -to_clock [get_clocks {i_clk}] -max_paths 25 -max_common_paths 1
report_timing -setup -from_clock [get_clocks {i_clk}] -to_clock [get_clocks {i_clk}] -max_paths 25 -max_common_paths 1
+227
View File
@@ -0,0 +1,227 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>2</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>ExternalFile</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>sram_srom</string>
</entry>
<entry>
<string>applicationType</string>
<appType>IVERILOG</appType>
</entry>
<entry>
<string>externalInputs</string>
<string>i_clk,i_rst,i_dir,i_act:2,i_addr:32,i_data:32</string>
</entry>
<entry>
<string>externalOutputs</string>
<string>o_data:32,o_we</string>
</entry>
<entry>
<string>Width</string>
<int>6</int>
</entry>
<entry>
<string>CodeFile</string>
<file>/Users/car/Projects/hope/sram_srom.v</file>
</entry>
</elementAttributes>
<pos x="240" y="220"/>
</visualElement>
<visualElement>
<elementName>Clock</elementName>
<elementAttributes/>
<pos x="100" y="220"/>
</visualElement>
<visualElement>
<elementName>Reset</elementName>
<elementAttributes>
<entry>
<string>invertOutput</string>
<boolean>false</boolean>
</entry>
</elementAttributes>
<pos x="100" y="260"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>dir</string>
</entry>
<entry>
<string>InDefault</string>
<value v="1" z="false"/>
</entry>
</elementAttributes>
<pos x="100" y="300"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>act</string>
</entry>
<entry>
<string>Bits</string>
<int>2</int>
</entry>
<entry>
<string>InDefault</string>
<value v="1" z="false"/>
</entry>
</elementAttributes>
<pos x="100" y="360"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>addr</string>
</entry>
<entry>
<string>Bits</string>
<int>32</int>
</entry>
<entry>
<string>InDefault</string>
<value v="16388" z="false"/>
</entry>
</elementAttributes>
<pos x="100" y="420"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>data in</string>
</entry>
<entry>
<string>Bits</string>
<int>32</int>
</entry>
<entry>
<string>InDefault</string>
<value v="1985229328" z="false"/>
</entry>
</elementAttributes>
<pos x="100" y="480"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>data out</string>
</entry>
<entry>
<string>Bits</string>
<int>32</int>
</entry>
</elementAttributes>
<pos x="400" y="220"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>we</string>
</entry>
</elementAttributes>
<pos x="400" y="260"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="140" y="240"/>
<p2 x="240" y="240"/>
</wire>
<wire>
<p1 x="360" y="240"/>
<p2 x="380" y="240"/>
</wire>
<wire>
<p1 x="220" y="320"/>
<p2 x="240" y="320"/>
</wire>
<wire>
<p1 x="100" y="480"/>
<p2 x="220" y="480"/>
</wire>
<wire>
<p1 x="100" y="260"/>
<p2 x="140" y="260"/>
</wire>
<wire>
<p1 x="160" y="260"/>
<p2 x="240" y="260"/>
</wire>
<wire>
<p1 x="380" y="260"/>
<p2 x="400" y="260"/>
</wire>
<wire>
<p1 x="100" y="420"/>
<p2 x="200" y="420"/>
</wire>
<wire>
<p1 x="100" y="360"/>
<p2 x="180" y="360"/>
</wire>
<wire>
<p1 x="180" y="280"/>
<p2 x="240" y="280"/>
</wire>
<wire>
<p1 x="100" y="220"/>
<p2 x="240" y="220"/>
</wire>
<wire>
<p1 x="360" y="220"/>
<p2 x="400" y="220"/>
</wire>
<wire>
<p1 x="100" y="300"/>
<p2 x="160" y="300"/>
</wire>
<wire>
<p1 x="200" y="300"/>
<p2 x="240" y="300"/>
</wire>
<wire>
<p1 x="160" y="260"/>
<p2 x="160" y="300"/>
</wire>
<wire>
<p1 x="180" y="280"/>
<p2 x="180" y="360"/>
</wire>
<wire>
<p1 x="200" y="300"/>
<p2 x="200" y="420"/>
</wire>
<wire>
<p1 x="140" y="240"/>
<p2 x="140" y="260"/>
</wire>
<wire>
<p1 x="220" y="320"/>
<p2 x="220" y="480"/>
</wire>
<wire>
<p1 x="380" y="240"/>
<p2 x="380" y="260"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>
+38
View File
@@ -0,0 +1,38 @@
module testbram
(input i_clk,
input i_rst,
input i_dir,
input [1:0] i_act,
input [31:0] i_addr,
input [31:0] i_data,
output reg [31:0] o_data,
output o_we);
(* ram_style = "block" *)
reg [31:0] sram [4095:0];
(* ram_style = "block" *)
reg [31:0] srom [4095:0];
wire use_ram = (i_addr >= 32'h00004000) && (i_addr < 32'h00008000);
wire use_rom = (i_addr < 32'h00004000);
assign o_we = ~i_dir && (i_act != 2'b00);
// WRITE - simplest possible
always @(posedge i_clk) begin
if (i_dir && use_ram)
sram[i_addr[13:2]] <= i_data;
end
// READ - simplest possible
always @(posedge i_clk) begin
if (use_ram)
o_data <= sram[i_addr[13:2]];
else if (use_rom)
o_data <= srom[i_addr[13:2]];
else
o_data <= 32'h0;
end
endmodule
Executable
+354
View File
@@ -0,0 +1,354 @@
#!/usr/bin/env python3
"""
Microcode Assembler for microcoded CPU
Parses .src files and generates Verilog hex files
"""
import sys
import re
class Field:
"""Represents a microcode field definition"""
def __init__(self, name, width, default, enums):
self.name = name
self.width = width
self.default = default # Can be int or str
self.enums = enums # Dict of name -> value
self.position = 0 # Bit position (set later)
def encode(self, value):
"""Encode a value for this field"""
if isinstance(value, str):
if value in self.enums:
return self.enums[value]
else:
raise ValueError(f"Unknown enum '{value}' for field '{self.name}'. Valid: {list(self.enums.keys())}")
return int(value)
class MicrocodeAssembler:
def __init__(self):
self.fields = []
self.field_map = {}
self.subroutines = []
self.sub_addresses = {}
# Config
self.microcode_length = 512
self.microcode_width = 36
self.microcode_output = 'ucode.hex'
self.mapping_length = 32
self.mapping_output = 'umap.hex'
self.mapping_entries = [0] * 32 # Default all to 0 (fetch)
def parse_config(self, line):
"""Parse configuration lines"""
parts = line.split()
if len(parts) < 3:
return
category, key, value = parts[0], parts[1], parts[2]
if category == 'microcode':
if key == 'length':
self.microcode_length = int(value)
elif key == 'width':
self.microcode_width = int(value)
elif key == 'output':
self.microcode_output = value
elif category == 'mapping':
if key == 'length':
self.mapping_length = int(value)
self.mapping_entries = [0] * self.mapping_length
elif key == 'output':
self.mapping_output = value
def parse_field(self, line):
"""
Parse field definition: field <name> <width> <default> [enums]
Example: field rd 3 imm pcp=0,dsp=1,rsp=2,tmp=3,mdr=4,tos=5,acc=6,imm=7
"""
parts = line.split(None, 3) # Split into max 4 parts
if len(parts) < 4:
raise ValueError(f"Invalid field: {line}")
name = parts[1]
width = int(parts[2])
rest = parts[3] # "default [enums...]"
# Split rest into tokens
tokens = rest.split()
default_str = tokens[0]
# Parse enums (everything after first token, comma-separated)
enums = {}
if len(tokens) > 1:
enum_str = ' '.join(tokens[1:])
for i, item in enumerate(enum_str.split(',')):
item = item.strip()
if '=' in item:
k, v = item.split('=')
enums[k.strip()] = int(v.strip())
else:
enums[item] = i
# Resolve default
if default_str.isdigit():
default_value = int(default_str)
elif default_str in enums:
default_value = enums[default_str]
else:
# Default is a symbolic name (like 'imm') that should be in enums
# If not in enums yet, we'll handle it during encoding
default_value = default_str
field = Field(name, width, default_value, enums)
self.fields.append(field)
self.field_map[name] = field
def layout_fields(self):
"""Assign bit positions to fields (LSB first)"""
pos = 0
for field in self.fields:
field.position = pos
pos += field.width
if pos != self.microcode_width:
print(f"Warning: Fields total {pos} bits, microcode width is {self.microcode_width}")
def parse_subroutine(self, lines, start_idx):
"""Parse a subroutine block, returns (name, address, instructions, next_idx)"""
# sub <name> [address]
sub_match = re.match(r'sub\s+(\w+)(?:\s+([0-9A-Fa-fx]+h?))?', lines[start_idx])
if not sub_match:
raise ValueError(f"Invalid sub: {lines[start_idx]}")
name = sub_match.group(1)
address = None
if sub_match.group(2):
addr_str = sub_match.group(2).replace('h', '').replace('x', '')
address = int(addr_str, 16)
# Collect instructions until 'end'
instructions = []
idx = start_idx + 1
while idx < len(lines):
line = lines[idx].strip()
if line.startswith('end'):
break
if line and not line.startswith(';'):
instructions.append(line)
idx += 1
return name, address, instructions, idx + 1
def parse_map(self, line):
"""Parse map statement"""
# map entry1,entry2,entry3*count,...
map_content = line[3:].strip()
entries = [e.strip() for e in map_content.split(',')]
map_idx = 0
for entry in entries:
if '*' in entry:
# Repeat entry
name, count_str = entry.split('*')
name = name.strip()
count = int(count_str.strip())
if name not in self.sub_addresses:
raise ValueError(f"Unknown subroutine '{name}' in map")
addr = self.sub_addresses[name]
for _ in range(count):
if map_idx >= self.mapping_length:
raise ValueError("Map overflow")
self.mapping_entries[map_idx] = addr
map_idx += 1
else:
# Single entry
if entry not in self.sub_addresses:
raise ValueError(f"Unknown subroutine '{entry}' in map")
self.mapping_entries[map_idx] = self.sub_addresses[entry]
map_idx += 1
def assemble_instruction(self, inst_line):
"""Assemble a microcode instruction line into a word"""
# Initialize with defaults
field_values = {}
for field in self.fields:
if isinstance(field.default, str):
# Resolve symbolic default
if field.default in field.enums:
field_values[field.name] = field.enums[field.default]
else:
raise ValueError(f"Default '{field.default}' not in enums for field '{field.name}'")
else:
field_values[field.name] = field.default
# Parse assignments
for assign in inst_line.split(','):
assign = assign.strip()
if '=' in assign:
field_name, value_str = assign.split('=', 1)
field_name = field_name.strip()
value_str = value_str.strip()
if field_name not in self.field_map:
raise ValueError(f"Unknown field '{field_name}': {inst_line}")
field = self.field_map[field_name]
# Parse value
if value_str.endswith('h'):
value = int(value_str[:-1], 16)
elif value_str.startswith('0x'):
value = int(value_str, 16)
elif value_str.isdigit():
value = int(value_str)
else:
# Symbolic value
value = field.encode(value_str)
field_values[field_name] = value
else:
# Just field name -> set to 1
if assign not in self.field_map:
raise ValueError(f"Unknown field '{assign}': {inst_line}")
field_values[assign] = 1
# Pack into word
word = 0
for field in self.fields:
value = field_values[field.name]
if value >= (1 << field.width):
raise ValueError(f"Value {value} too large for field '{field.name}' (width {field.width})")
word |= (value << field.position)
return word
def assemble(self, source_file):
"""Main assembly"""
with open(source_file, 'r') as f:
lines = [line.strip() for line in f.readlines()]
# Pass 1: Config and fields
idx = 0
while idx < len(lines):
line = lines[idx]
if not line or line.startswith(';'):
idx += 1
continue
if line.startswith('microcode') or line.startswith('mapping'):
self.parse_config(line)
elif line.startswith('field'):
self.parse_field(line)
elif line.startswith('sub'):
break
idx += 1
self.layout_fields()
# Pass 2: Subroutines
while idx < len(lines):
line = lines[idx]
if not line or line.startswith(';'):
idx += 1
continue
if line.startswith('sub'):
name, address, instructions, next_idx = self.parse_subroutine(lines, idx)
self.subroutines.append((name, address, instructions))
idx = next_idx
elif line.startswith('map'):
break
else:
idx += 1
# Assign addresses - FIXED ALGORITHM
# Build a set of all occupied addresses from explicit subroutines
occupied = set()
for name, address, instructions in self.subroutines:
if address is not None:
self.sub_addresses[name] = address
# Mark all addresses this subroutine occupies
for i in range(len(instructions)):
occupied.add(address + i)
# Now assign auto addresses to remaining subroutines
auto_addr = 0
for name, address, instructions in self.subroutines:
if address is None:
# Find next sequence of free addresses long enough for this subroutine
while any((auto_addr + i) in occupied for i in range(len(instructions))):
auto_addr += 1
self.sub_addresses[name] = auto_addr
# Mark these addresses as occupied
for i in range(len(instructions)):
occupied.add(auto_addr + i)
auto_addr += len(instructions)
# Pass 3: Map
while idx < len(lines):
line = lines[idx]
if not line or line.startswith(';'):
idx += 1
continue
if line.startswith('map'):
self.parse_map(line)
idx += 1
# Generate microcode ROM
microcode_rom = [0] * self.microcode_length
for name, _, instructions in self.subroutines:
addr = self.sub_addresses[name]
for inst in instructions:
if addr >= self.microcode_length:
raise ValueError(f"Address {addr} overflow")
microcode_rom[addr] = self.assemble_instruction(inst)
addr += 1
# Write outputs
self.write_hex(self.microcode_output, microcode_rom, self.microcode_width)
self.write_hex(self.mapping_output, self.mapping_entries, 9)
print(f"Assembly complete!")
print(f" Microcode: {self.microcode_output}")
print(f" Mapping: {self.mapping_output}")
print(f"\nSubroutines:")
for name, addr in sorted(self.sub_addresses.items(), key=lambda x: x[1]):
# Find instruction count
inst_count = next(len(inst) for n, a, inst in self.subroutines if n == name)
print(f" {name:12s} @ 0x{addr:03X} ({inst_count} instructions)")
def write_hex(self, filename, data, width):
"""Write Verilog hex file"""
with open(filename, 'w') as f:
hex_digits = (width + 3) // 4
for word in data:
f.write(f"{word:0{hex_digits}X}\n")
def main():
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <source.src>")
sys.exit(1)
asm = MicrocodeAssembler()
try:
asm.assemble(sys.argv[1])
except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
if __name__ == '__main__':
main()
+512
View File
@@ -0,0 +1,512 @@
000007F8C
002C10C10
000885690
000004D90
008019CB4
0008852F0
000004D90
002010C1C
0008852F0
008011C90
000005E10
000007FA5
002010C1C
000804E90
008011C90
000005E10
000007FA5
002010C1C
01005CE90
002010C1C
00084D290
008011C90
000005E10
000007FA5
002010C1C
01005CE90
002010C1C
00004D290
01005CE90
002010C1C
00004D290
01005CE90
002010C1C
00084D290
000807F80
000807F80
000007FA4
000004F10
000005E10
000007FA5
000806E90
008011C90
000005E10
000807FA5
008019CB4
000804E90
000005D90
000007FE4
000804E90
000005D90
000007FEC
000804E90
000005D90
00801AD74
000007FC5
008019CB4
000804E90
000005D90
00801AD7C
000007FC5
008019CB4
000804E90
000005D90
008019CB4
000007FE5
008019CB4
000804E90
000005D90
008019CB4
000007FED
008019CB4
000804E90
008011C90
000005E10
000007FA5
008012D54
000804E90
00801AD10
000005E10
000007FC5
008019CB4
000804E90
000807F80
000807F80
000005C10
008019CB4
000804E90
008019CB4
000004F10
000005D90
008019CB4
000004E90
000B06F80
000803C10
008019CB4
000004F10
000005D90
008019CB4
000004E90
000A06F80
000803C10
00801AD10
000000E10
000007FC5
000005C10
008019CB4
000804E90
008019CB4
000004F10
000005D90
008019CB4
000004E90
000B06F80
00801AD10
000000E10
000007FC5
000803C10
008019CB4
000004F10
000005D90
008019CB4
000004E90
000A06F80
00801AD10
000000E10
000007FC5
000803C10
008012D54
000804C10
000005F10
008019CB4
000004E90
000B06F80
008012D54
000804C10
000005F10
008019CB4
000004E90
000A06F80
008012D54
000804C10
008011C90
000005E10
008019DB5
000007FE4
000804E90
000007FC4
00201CE10
3C0A04F80
000007FC5
002010C1C
000074E10
000810010
000807F80
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
00801AD1C
000810C10
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000000000
000007F80
080007C90
010059C90
088007D10
01005AD10
000807F80
000000000
000000000
+419
View File
@@ -0,0 +1,419 @@
; Copyright (C) 2026 Paul Carver Harrison
microcode length 512
microcode width 36
microcode padding left
microcode target vhex
microcode output ucode.hex
mapping length 64
mapping target vhex
mapping output umap.hex
field md 1 0 read=0,write=1
field mssrc 1 0 ucode=0,rma=1
field ms 2 0 nop=0,word=1,hword=2,byte=3
field rwe 1 0
field rma 2 0 pcp=0,dsp=1,rsp=2,tmp=3
field rd 3 imm pcp=0,dsp=1,rsp=2,tmp=3,mdr=4,tos=5,acc=6,imm=7
field rs2 2 imm mdr=0,tos=1,acc=2,imm=3
field rs1 3 imm pcp=0,dsp=1,rsp=2,tmp=3,mdr=4,tos=5,acc=6,imm=7
field aluop 4 0 a,not,add,sub,sgt,slt,gt,lt,and,or,xor,lsl,asr,mul,sextb,sexth
field alusrc 1 0 ucode=0,rma=1
field cci 1 0
field cce 1 0
field seqsrc 1 0 imm=0,map=1
field seqop 2 0 step=0,jump=1,retn=2,call=3
field imm 9 0
sub fetch 000h
; fetch instruction and increment pcp. jump to instruction
rma=pcp,md=read,ms=byte
rwe,aluop=add,rd=pcp,rs1=pcp,imm=1,seqop=jump,seqsrc=map
end
sub aluop1
rwe,alusrc=rma,rd=tos,rs1=tos,rs2=tos,seqop=retn
end
sub aluop2
rwe,aluop=a,rd=tmp,rs1=mdr
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,alusrc=rma,rma=tmp,rd=tos,rs1=tos,rs2=mdr,seqop=retn
end
sub aluopi
rwe,aluop=a,rd=tmp,rs1=mdr
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,alusrc=rma,rma=tmp,rd=tos,rs1=tos,rs2=mdr,seqop=retn
end
sub pushdb
; *(++((word *)dsp)) = tos
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word
; tos = *pcp++
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub pushdhu
; *(++((word *)dsp)) = tos
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word
; read half-word into tos
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=lsl,rd=tos,rs1=mdr,imm=8
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=or,rd=tos,rs1=tos,rs2=mdr,seqop=retn
end
sub pushdwu
; *(++((word *)dsp)) = tos
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word
; read word into tos
; 0
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=lsl,rd=tos,rs1=mdr,imm=8
; 1
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=or,rd=tos,rs1=tos,rs2=mdr
rwe,aluop=lsl,rd=tos,rs1=mdr,imm=8
; 2
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=or,rd=tos,rs1=tos,rs2=mdr
rwe,aluop=lsl,rd=tos,rs1=mdr,imm=8
; 3
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=or,rd=tos,rs1=tos,rs2=mdr,seqop=retn
end
sub pushdha
seqop=retn
end
sub pushdwa
seqop=retn
end
sub swap
rma=dsp,md=read,ms=word
rd=acc,rs1=mdr,rwe,aluop=a
rd=mdr,rs1=tos,rwe,aluop=a
rma=dsp,md=write,ms=word
rd=tos,rs1=acc,rwe,aluop=a,seqop=retn
end
sub dup
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word,seqop=retn
end
sub drop
; tos = *(((word *)dsp)--)
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
; fetch word from memory and store on data stack
sub fetchdw
; tmp = tos
rwe,aluop=a,rd=tmp,rs1=tos
; mdr = *(word *)tmp
rma=tmp,md=read,ms=word
; tos = mdr
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
; fetch byte from memory and store on data stack
sub fetchdb
rwe,aluop=a,rd=tmp,rs1=tos
rma=tmp,md=read,ms=byte
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
; fetch word from memory and store on return stack
sub fetchrw
; mdr = *(word *)tos; rsp -= 4
rwe,aluop=a,rd=tmp,rs1=tos
rma=tmp,md=read,ms=word,rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
; push onto return stack
rma=rsp,md=write,ms=word
; pop off data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
; fetch byte from memory and store on return stack
sub fetchrb
; mdr = *(byte *)tos; rsp -= 4
rwe,aluop=a,rd=tmp,rs1=tos
rma=tmp,md=read,ms=byte,rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
; push onto return stack
rma=rsp,md=write,ms=word
; pop off data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub storedw
; mdr = *(word *)tos; dsp -= 4
rwe,aluop=a,rd=tmp,rs1=tos
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rma=tmp,md=write,ms=word
; pop off data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub storedb
; mdr = *(word *)tos; dsp -= 4
rwe,aluop=a,rd=tmp,rs1=tos
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rma=tmp,md=write,ms=byte
; pop off data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub rtod
; push TOS onto data stack
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word
; pop top of return stack into TOS
rma=rsp,md=read,ms=word,rwe,aluop=add,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub dtor
; push TOS onto return stack
rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=rsp,md=write,ms=word
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub pstoredw
seqop=retn
end
sub pstoredb
seqop=retn
end
sub jump
; transfer TOS to PCP
rwe,aluop=a,rd=pcp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub jumpz
; ACC = NOS = value to check
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=acc,rs1=mdr
; TMP = TOS = branch address
rwe,aluop=a,rd=tmp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If not zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=1,seqop=retn
; If zero, jump to address in TMP
rwe,aluop=a,rd=pcp,rs1=tmp,seqop=retn
end
sub jumpnz
; ACC = NOS = value to check
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=acc,rs1=mdr
; TMP = TOS = branch address
rwe,aluop=a,rd=tmp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=0,seqop=retn
; If not zero, jump to address in TMP
rwe,aluop=a,rd=pcp,rs1=tmp,seqop=retn
end
sub call
; push PCP onto return stack
rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=mdr,rs1=pcp
rma=rsp,md=write,ms=word
; PCP = TOS
rwe,aluop=a,rd=pcp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub callz
; ACC = NOS = value to check
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=acc,rs1=mdr
; TMP = TOS = branch address
rwe,aluop=a,rd=tmp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If not zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=1,seqop=retn
; push PCP onto return stack
rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=mdr,rs1=pcp
rma=rsp,md=write,ms=word
; If zero, jump to address in TMP
rwe,aluop=a,rd=pcp,rs1=tmp,seqop=retn
end
sub callnz
; ACC = NOS = value to check
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=acc,rs1=mdr
; TMP = TOS = branch address
rwe,aluop=a,rd=tmp,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=0,seqop=retn
; push PCP onto return stack
rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=mdr,rs1=pcp
rma=rsp,md=write,ms=word
; If not zero, jump to address in TMP
rwe,aluop=a,rd=pcp,rs1=tmp,seqop=retn
end
sub ret
rma=rsp,md=read,ms=word,rwe,aluop=add,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=pcp,rs1=mdr,seqop=retn
end
sub retz
; ACC = TOS = value to check
rwe,aluop=a,rd=acc,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If not zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=1,seqop=retn
; return
rma=rsp,md=read,ms=word,rwe,aluop=add,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=pcp,rs1=mdr,seqop=retn
end
sub retnz
; ACC = TOS = value to check
rwe,aluop=a,rd=acc,rs1=tos
; pop top of data stack into TOS
rma=dsp,md=read,ms=word,rwe,aluop=sub,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=tos,rs1=mdr
; If zero, next ISA instruction
aluop=a,rs1=acc,cce=1,cci=0,seqop=retn
; return
rma=rsp,md=read,ms=word,rwe,aluop=add,rd=rsp,rs1=rsp,imm=4
rwe,aluop=a,rd=pcp,rs1=mdr,seqop=retn
end
sub over
rwe,aluop=add,rd=dsp,rs1=dsp,imm=4
rwe,aluop=a,rd=mdr,rs1=tos
rma=dsp,md=write,ms=word,rwe,aluop=sub,rd=tmp,rs1=dsp,imm=4
rma=tmp,md=read,ms=word
rwe,aluop=a,rd=tos,rs1=mdr,seqop=retn
end
sub repeatri
rma=rsp,md=read,ms=word
rwe,aluop=sub,rd=mdr,rs1=mdr,imm=1
aluop=a,rs1=mdr,cce,seqop=jump,imm=1E0h
rma=rsp,md=write,ms=word
rma=pcp,md=read,ms=byte,rwe,aluop=add,rd=pcp,rs1=pcp,imm=1
rwe,aluop=sextb,rd=mdr,rs1=mdr
rwe,aluop=add,rd=pcp,rs1=pcp,rs2=mdr,seqop=retn
end
sub rot
seqop=call,imm=dtor
seqop=call,imm=swap
seqop=call,imm=rtod
seqop=call,imm=swap
seqop=retn
sub nop
seqop=retn
end
sub repeatri_ret 1EEh
rma=pcp,md=read,ms=byte,rwe,aluop=sub,rd=rsp,rs1=rsp,imm=4
rwe,aluop=add,rd=pcp,rs1=pcp,imm=1,seqop=retn
end
sub init 1F8h
; nop required on startup
imm=0
; data stack starts at 4000h and grows up
rwe,aluop=a,rd=dsp,imm=40h
rwe,aluop=lsl,rd=dsp,rs1=dsp,imm=8
; return stack starts at 4400h and grows down
rwe,aluop=a,rd=rsp,imm=44h
rwe,aluop=lsl,rd=rsp,rs1=rsp,imm=8
; init done
seqop=retn
end
map aluop1*4,aluop2*4,aluopi*4,swap,dup,drop,over,fetchdw,fetchdb,fetchrw,fetchrb,storedw,storedb,pstoredw,pstoredb,rtod,dtor,jump,jumpz,jumpnz,call,callz,callnz,ret,retz,retnz,pushdb,pushdhu,pushdwu,pushdha,pushdwa,repeatri
+64
View File
@@ -0,0 +1,64 @@
002
002
002
002
003
003
003
003
006
006
006
006
024
029
02C
08D
02E
031
034
039
03E
043
052
053
048
04D
054
057
05E
065
06B
075
07F
081
087
009
00E
015
022
023
092
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
000
View File
+51
View File
@@ -0,0 +1,51 @@
module vdp
(input i_clk,
input i_rst,
output o_r,
output o_g,
output o_b,
output o_hsync,
output o_vsync);
wire [12:0] cg_addr;
wire [15:0] cg_data;
wire [10:0] row;
wire [10:0] col;
wire hsync;
wire vsync;
wire de;
assign o_hsync = ~hsync;
assign o_vsync = ~vsync;
vga_timing_gen vga_timing_gen_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.o_hsync(hsync),
.o_vsync(vsync),
.o_row(row),
.o_col(col),
.o_de(de));
chargen chargen_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.i_row(row),
.i_col(col),
.i_de(de),
.i_ram_data(cg_data),
.o_ram_addr(cg_addr),
.o_r(o_r),
.o_g(o_g),
.o_b(o_b));
charram charram_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.i_cpu_addr(13'd0),
.i_cpu_data(16'd0),
.i_cpu_we(1'b0),
.i_gen_addr(cg_addr),
.o_gen_data(cg_data));
endmodule
+129
View File
@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>2</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>ExternalFile</elementName>
<elementAttributes>
<entry>
<string>applicationType</string>
<appType>IVERILOG</appType>
</entry>
<entry>
<string>Label</string>
<string>vdp</string>
</entry>
<entry>
<string>externalInputs</string>
<string>i_clk,i_rst</string>
</entry>
<entry>
<string>Width</string>
<int>8</int>
</entry>
<entry>
<string>externalOutputs</string>
<string>o_r,o_g,o_b,o_hsync,o_vsync</string>
</entry>
<entry>
<string>iverilogOptions</string>
<string>/Users/car/Projects/hope/chargen.sv /Users/car/Projects/hope/charram.sv /Users/car/Projects/hope/vga_timing_gen.sv</string>
</entry>
<entry>
<string>CodeFile</string>
<file>/Users/car/Projects/hope/vdp.sv</file>
</entry>
</elementAttributes>
<pos x="440" y="280"/>
</visualElement>
<visualElement>
<elementName>Clock</elementName>
<elementAttributes>
<entry>
<string>runRealTime</string>
<boolean>true</boolean>
</entry>
<entry>
<string>Frequency</string>
<int>2147483647</int>
</entry>
</elementAttributes>
<pos x="320" y="280"/>
</visualElement>
<visualElement>
<elementName>Reset</elementName>
<elementAttributes>
<entry>
<string>invertOutput</string>
<boolean>false</boolean>
</entry>
</elementAttributes>
<pos x="320" y="320"/>
</visualElement>
<visualElement>
<elementName>VGA</elementName>
<elementAttributes/>
<pos x="680" y="280"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="320" y="320"/>
<p2 x="360" y="320"/>
</wire>
<wire>
<p1 x="600" y="320"/>
<p2 x="680" y="320"/>
</wire>
<wire>
<p1 x="600" y="340"/>
<p2 x="680" y="340"/>
</wire>
<wire>
<p1 x="380" y="420"/>
<p2 x="600" y="420"/>
</wire>
<wire>
<p1 x="600" y="280"/>
<p2 x="680" y="280"/>
</wire>
<wire>
<p1 x="320" y="280"/>
<p2 x="380" y="280"/>
</wire>
<wire>
<p1 x="380" y="280"/>
<p2 x="440" y="280"/>
</wire>
<wire>
<p1 x="600" y="360"/>
<p2 x="680" y="360"/>
</wire>
<wire>
<p1 x="360" y="300"/>
<p2 x="440" y="300"/>
</wire>
<wire>
<p1 x="600" y="300"/>
<p2 x="680" y="300"/>
</wire>
<wire>
<p1 x="600" y="380"/>
<p2 x="680" y="380"/>
</wire>
<wire>
<p1 x="360" y="300"/>
<p2 x="360" y="320"/>
</wire>
<wire>
<p1 x="600" y="380"/>
<p2 x="600" y="420"/>
</wire>
<wire>
<p1 x="380" y="280"/>
<p2 x="380" y="420"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>
+182
View File
@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>2</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>ExternalFile</elementName>
<elementAttributes>
<entry>
<string>applicationType</string>
<appType>IVERILOG</appType>
</entry>
<entry>
<string>Label</string>
<string>vga_timing_gen</string>
</entry>
<entry>
<string>externalInputs</string>
<string>i_pclk,i_rst</string>
</entry>
<entry>
<string>externalOutputs</string>
<string>o_row:11,o_col:11,o_start,o_step,o_hsync,o_vsync</string>
</entry>
<entry>
<string>Width</string>
<int>8</int>
</entry>
<entry>
<string>CodeFile</string>
<file>/Users/car/Projects/hope/vga_timing_gen.sv</file>
</entry>
</elementAttributes>
<pos x="420" y="360"/>
</visualElement>
<visualElement>
<elementName>Clock</elementName>
<elementAttributes>
<entry>
<string>Frequency</string>
<int>50000</int>
</entry>
<entry>
<string>runRealTime</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="300" y="360"/>
</visualElement>
<visualElement>
<elementName>Button</elementName>
<elementAttributes/>
<pos x="300" y="400"/>
</visualElement>
<visualElement>
<elementName>VGA</elementName>
<elementAttributes/>
<pos x="720" y="380"/>
</visualElement>
<visualElement>
<elementName>Const</elementName>
<elementAttributes/>
<pos x="700" y="380"/>
</visualElement>
<visualElement>
<elementName>Const</elementName>
<elementAttributes/>
<pos x="700" y="400"/>
</visualElement>
<visualElement>
<elementName>Const</elementName>
<elementAttributes/>
<pos x="700" y="420"/>
</visualElement>
<visualElement>
<elementName>Counter</elementName>
<elementAttributes>
<entry>
<string>Bits</string>
<int>16</int>
</entry>
</elementAttributes>
<pos x="640" y="260"/>
</visualElement>
<visualElement>
<elementName>Probe</elementName>
<elementAttributes/>
<pos x="700" y="260"/>
</visualElement>
<visualElement>
<elementName>Const</elementName>
<elementAttributes/>
<pos x="640" y="260"/>
</visualElement>
<visualElement>
<elementName>Const</elementName>
<elementAttributes>
<entry>
<string>Value</string>
<long>0</long>
</entry>
</elementAttributes>
<pos x="640" y="300"/>
</visualElement>
<visualElement>
<elementName>Probe</elementName>
<elementAttributes/>
<pos x="580" y="360"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="300" y="400"/>
<p2 x="340" y="400"/>
</wire>
<wire>
<p1 x="700" y="400"/>
<p2 x="720" y="400"/>
</wire>
<wire>
<p1 x="700" y="480"/>
<p2 x="720" y="480"/>
</wire>
<wire>
<p1 x="700" y="420"/>
<p2 x="720" y="420"/>
</wire>
<wire>
<p1 x="300" y="360"/>
<p2 x="380" y="360"/>
</wire>
<wire>
<p1 x="380" y="360"/>
<p2 x="420" y="360"/>
</wire>
<wire>
<p1 x="580" y="440"/>
<p2 x="720" y="440"/>
</wire>
<wire>
<p1 x="380" y="520"/>
<p2 x="700" y="520"/>
</wire>
<wire>
<p1 x="620" y="280"/>
<p2 x="640" y="280"/>
</wire>
<wire>
<p1 x="340" y="380"/>
<p2 x="420" y="380"/>
</wire>
<wire>
<p1 x="700" y="380"/>
<p2 x="720" y="380"/>
</wire>
<wire>
<p1 x="580" y="460"/>
<p2 x="620" y="460"/>
</wire>
<wire>
<p1 x="620" y="460"/>
<p2 x="720" y="460"/>
</wire>
<wire>
<p1 x="340" y="380"/>
<p2 x="340" y="400"/>
</wire>
<wire>
<p1 x="380" y="360"/>
<p2 x="380" y="520"/>
</wire>
<wire>
<p1 x="700" y="480"/>
<p2 x="700" y="520"/>
</wire>
<wire>
<p1 x="620" y="280"/>
<p2 x="620" y="460"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>
+56
View File
@@ -0,0 +1,56 @@
module vga_timing_gen
#(parameter H_ACTIVE=640,
parameter H_FRONT=16,
parameter H_SYNC=96,
parameter H_BACK=48,
parameter V_ACTIVE=480,
parameter V_FRONT=10,
parameter V_SYNC=2,
parameter V_BACK=33)
(input i_clk,
input i_rst,
output logic [10:0] o_row,
output logic [10:0] o_col,
output o_de,
output logic o_hsync,
output logic o_vsync);
localparam H_TOTAL = H_ACTIVE + H_FRONT + H_SYNC + H_BACK;
localparam V_TOTAL = V_ACTIVE + V_FRONT + V_SYNC + V_BACK;
wire hsync;
wire vsync;
assign hsync = ((o_col >= H_ACTIVE + H_FRONT) && (o_col < H_ACTIVE + H_FRONT + H_SYNC));
assign vsync = ((o_row >= V_ACTIVE + V_FRONT) && (o_row < V_ACTIVE + V_FRONT + V_SYNC));
assign o_de = (o_row < V_ACTIVE) && (o_col < H_ACTIVE);
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
o_hsync <= 0;
o_vsync <= 0;
end else begin
o_hsync <= hsync;
o_vsync <= vsync;
end
end
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
o_row <= 11'd0;
o_col <= 11'd0;
end else if (o_col == H_TOTAL - 1) begin
o_col <= 11'd0;
if (o_row == V_TOTAL - 1) begin
o_row <= 11'd0;
end else begin
o_row <= o_row + 11'd1;
end
end else begin
o_col <= o_col + 11'd1;
o_row <= o_row;
end
end // always @ (posedge i_clk, posedge i_rst)
endmodule // vga_timing_gen
+42
View File
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>2</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>data in</string>
</entry>
<entry>
<string>Bits</string>
<int>32</int>
</entry>
</elementAttributes>
<pos x="200" y="180"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>data out</string>
</entry>
<entry>
<string>Bits</string>
<int>32</int>
</entry>
</elementAttributes>
<pos x="520" y="180"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes/>
<pos x="200" y="220"/>
</visualElement>
</visualElements>
<wires/>
<measurementOrdering/>
</circuit>
+178
View File
@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>2</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>halt</string>
</entry>
</elementAttributes>
<pos x="60" y="200"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>op</string>
</entry>
<entry>
<string>Bits</string>
<int>2</int>
</entry>
</elementAttributes>
<pos x="0" y="320"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>cc</string>
</entry>
</elementAttributes>
<pos x="0" y="420"/>
</visualElement>
<visualElement>
<elementName>Splitter</elementName>
<elementAttributes>
<entry>
<string>Input Splitting</string>
<string>1,1</string>
</entry>
<entry>
<string>Output Splitting</string>
<string>2</string>
</entry>
</elementAttributes>
<pos x="400" y="220"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
<elementAttributes>
<entry>
<string>wideShape</string>
<boolean>true</boolean>
</entry>
<entry>
<string>Inputs</string>
<int>3</int>
</entry>
</elementAttributes>
<pos x="240" y="200"/>
</visualElement>
<visualElement>
<elementName>Not</elementName>
<elementAttributes/>
<pos x="80" y="200"/>
</visualElement>
<visualElement>
<elementName>And</elementName>
<elementAttributes>
<entry>
<string>wideShape</string>
<boolean>true</boolean>
</entry>
<entry>
<string>Inputs</string>
<int>3</int>
</entry>
</elementAttributes>
<pos x="240" y="280"/>
</visualElement>
<visualElement>
<elementName>Probe</elementName>
<elementAttributes/>
<pos x="440" y="140"/>
</visualElement>
<visualElement>
<elementName>Splitter</elementName>
<elementAttributes>
<entry>
<string>Input Splitting</string>
<string>2</string>
</entry>
<entry>
<string>Output Splitting</string>
<string>1,1</string>
</entry>
</elementAttributes>
<pos x="60" y="320"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="340" y="240"/>
<p2 x="400" y="240"/>
</wire>
<wire>
<p1 x="0" y="320"/>
<p2 x="60" y="320"/>
</wire>
<wire>
<p1 x="0" y="420"/>
<p2 x="200" y="420"/>
</wire>
<wire>
<p1 x="60" y="200"/>
<p2 x="80" y="200"/>
</wire>
<wire>
<p1 x="120" y="200"/>
<p2 x="220" y="200"/>
</wire>
<wire>
<p1 x="220" y="200"/>
<p2 x="240" y="200"/>
</wire>
<wire>
<p1 x="220" y="280"/>
<p2 x="240" y="280"/>
</wire>
<wire>
<p1 x="420" y="220"/>
<p2 x="440" y="220"/>
</wire>
<wire>
<p1 x="320" y="220"/>
<p2 x="400" y="220"/>
</wire>
<wire>
<p1 x="200" y="220"/>
<p2 x="240" y="220"/>
</wire>
<wire>
<p1 x="320" y="300"/>
<p2 x="340" y="300"/>
</wire>
<wire>
<p1 x="200" y="300"/>
<p2 x="240" y="300"/>
</wire>
<wire>
<p1 x="340" y="240"/>
<p2 x="340" y="300"/>
</wire>
<wire>
<p1 x="440" y="140"/>
<p2 x="440" y="220"/>
</wire>
<wire>
<p1 x="200" y="220"/>
<p2 x="200" y="300"/>
</wire>
<wire>
<p1 x="200" y="300"/>
<p2 x="200" y="420"/>
</wire>
<wire>
<p1 x="220" y="200"/>
<p2 x="220" y="280"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>