32bit stack machine
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
a.out
|
||||
*~
|
||||
\#*
|
||||
*.vcd
|
||||
*.log
|
||||
*.json
|
||||
.DS_Store
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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("MDR←MEM[%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
|
||||
@@ -0,0 +1,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
void main() {
|
||||
for (;;)
|
||||
printf("Digital:0\nDigital:1\n");
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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">    |--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">    |--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">    |--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">    |--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>
|
||||
@@ -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>
|
||||
@@ -0,0 +1 @@
|
||||
syn_ide_mode=true
|
||||
@@ -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
|
||||
@@ -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
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Binary file not shown.
Executable
+2146
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
@@ -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>
|
||||
@@ -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
@@ -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.
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -0,0 +1,8 @@
|
||||
8434088c
|
||||
8c008c64
|
||||
30123c01
|
||||
8038fba0
|
||||
098c088c
|
||||
68108c74
|
||||
048c108c
|
||||
681a8c12
|
||||
@@ -0,0 +1,8 @@
|
||||
8c083484
|
||||
648c008c
|
||||
013c1230
|
||||
a0fb3880
|
||||
8c088c09
|
||||
748c1068
|
||||
8c108c04
|
||||
128c1a68
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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()
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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
@@ -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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user