Merge branch 'uart' into 'master'
Add UART TX Module See merge request bslathi19/super6502!3
This commit is contained in:
@@ -2,11 +2,13 @@ module addr_decode(
|
||||
input logic [15:0] addr,
|
||||
output logic ram_cs,
|
||||
output logic rom_cs,
|
||||
output logic hex_cs
|
||||
output logic hex_cs,
|
||||
output logic uart_cs
|
||||
);
|
||||
|
||||
assign rom_cs = addr[15];
|
||||
assign ram_cs = ~addr[15] && addr < 16'h7ff0;
|
||||
assign hex_cs = addr >= 16'h7ff0 && addr < 16'h7ff4;
|
||||
assign uart_cs = addr >= 16'h7ff4 && addr < 16'h7ff6;
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -8,8 +8,9 @@ logic [15:0] addr;
|
||||
logic ram_cs;
|
||||
logic rom_cs;
|
||||
logic hex_cs;
|
||||
logic uart_cs;
|
||||
|
||||
int cs_count = ram_cs + rom_cs + hex_cs;
|
||||
int cs_count = ram_cs + rom_cs + hex_cs + uart_cs;
|
||||
|
||||
addr_decode dut(.*);
|
||||
|
||||
@@ -29,7 +30,12 @@ initial begin : TEST_VECTORS
|
||||
if (i >= 16'h7ff0 && i < 16'h7ff4) begin
|
||||
assert(hex_cs == '1)
|
||||
else
|
||||
$error("Bad CS! addr=%4x should have io_cs!", addr);
|
||||
$error("Bad CS! addr=%4x should have hex_cs!", addr);
|
||||
end
|
||||
if (i >= 16'h7ff4 && i < 16'6) begin
|
||||
assert(uart_cs == '1)
|
||||
else
|
||||
$error("Bad CS! addr=%4x should have uart_cs!", addr);
|
||||
end
|
||||
if (i >= 2**15) begin
|
||||
assert(rom_cs == '1)
|
||||
|
||||
60
hw/fpga/hvl/uart_testbench.sv
Normal file
60
hw/fpga/hvl/uart_testbench.sv
Normal file
@@ -0,0 +1,60 @@
|
||||
module testbench();
|
||||
|
||||
timeunit 10ns;
|
||||
|
||||
timeprecision 1ns;
|
||||
|
||||
logic clk_50, clk, rst, cs;
|
||||
logic [1:0] addr;
|
||||
logic [7:0] data_in, data_out;
|
||||
logic rw;
|
||||
logic RXD, TXD;
|
||||
|
||||
logic [7:0] status;
|
||||
|
||||
uart dut(.*);
|
||||
|
||||
always #1 clk_50 = clk_50 === 1'b0;
|
||||
always #100 clk = clk === 1'b0;
|
||||
|
||||
task write(logic [7:0] data);
|
||||
@(negedge clk);
|
||||
cs <= '1;
|
||||
addr <= '0;
|
||||
data_in <= data;
|
||||
rw <= '0;
|
||||
|
||||
@(negedge clk);
|
||||
cs <= '0;
|
||||
addr <= '0;
|
||||
data_in <= 8'hxx;
|
||||
rw <= '1;
|
||||
|
||||
do begin
|
||||
@(negedge clk);
|
||||
cs <= '1;
|
||||
addr <= 1'b1;
|
||||
rw <= '1;
|
||||
@(negedge clk);
|
||||
end while (data_out != 8'h0);
|
||||
endtask
|
||||
|
||||
task puts(string s, int n);
|
||||
for (int i = 0; i < n; i++)
|
||||
write(s[i]);
|
||||
endtask
|
||||
|
||||
initial begin
|
||||
rst <= '1;
|
||||
repeat(5) @(posedge clk);
|
||||
rst <= '0;
|
||||
rw <= '1;
|
||||
cs <= '0;
|
||||
status <= '0;
|
||||
|
||||
puts("Hello, world!\n", 14);
|
||||
|
||||
$finish();
|
||||
end
|
||||
|
||||
endmodule
|
||||
4
hw/fpga/simulation/modelsim/.gitignore
vendored
4
hw/fpga/simulation/modelsim/.gitignore
vendored
@@ -8,7 +8,7 @@
|
||||
*.dat
|
||||
*.dbs
|
||||
*.psm
|
||||
*.bak
|
||||
*.bak*
|
||||
*.cmp
|
||||
*.jpg
|
||||
*.html
|
||||
@@ -20,7 +20,7 @@ wlf*
|
||||
*.vstf
|
||||
*.ucdb
|
||||
cov*/
|
||||
transcript*
|
||||
*transcript*
|
||||
sc_dpiheader.h
|
||||
vsim.dbg
|
||||
*.sft
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
transcript on
|
||||
if {[file exists rtl_work]} {
|
||||
vdel -lib rtl_work -all
|
||||
}
|
||||
vlib rtl_work
|
||||
vmap work rtl_work
|
||||
|
||||
vlog -vlog01compat -work work +incdir+/home/byron/Projects/super6502/hw/fpga {/home/byron/Projects/super6502/hw/fpga/ram.v}
|
||||
vlog -vlog01compat -work work +incdir+/home/byron/Projects/super6502/hw/fpga {/home/byron/Projects/super6502/hw/fpga/rom.v}
|
||||
vlog -vlog01compat -work work +incdir+/home/byron/Projects/super6502/hw/fpga {/home/byron/Projects/super6502/hw/fpga/cpu_clk.v}
|
||||
vlog -vlog01compat -work work +incdir+/home/byron/Projects/super6502/hw/fpga/db {/home/byron/Projects/super6502/hw/fpga/db/cpu_clk_altpll.v}
|
||||
vlog -sv -work work +incdir+/home/byron/Projects/super6502/hw/fpga {/home/byron/Projects/super6502/hw/fpga/uart.sv}
|
||||
vlog -sv -work work +incdir+/home/byron/Projects/super6502/hw/fpga {/home/byron/Projects/super6502/hw/fpga/addr_decode.sv}
|
||||
vlog -sv -work work +incdir+/home/byron/Projects/super6502/hw/fpga {/home/byron/Projects/super6502/hw/fpga/super6502.sv}
|
||||
vlog -sv -work work +incdir+/home/byron/Projects/super6502/hw/fpga {/home/byron/Projects/super6502/hw/fpga/HexDriver.sv}
|
||||
vlog -sv -work work +incdir+/home/byron/Projects/super6502/hw/fpga {/home/byron/Projects/super6502/hw/fpga/SevenSeg.sv}
|
||||
|
||||
17
hw/fpga/simulation/modelsim/uart.do
Normal file
17
hw/fpga/simulation/modelsim/uart.do
Normal file
@@ -0,0 +1,17 @@
|
||||
transcript on
|
||||
if {[file exists rtl_work]} {
|
||||
vdel -lib rtl_work -all
|
||||
}
|
||||
vlib rtl_work
|
||||
vmap work rtl_work
|
||||
|
||||
vlog -sv -work work {../../uart.sv}
|
||||
vlog -sv -work work {../../hvl/uart_testbench.sv}
|
||||
|
||||
vsim -t 1ps -L altera_ver -L lpm_ver -L sgate_ver -L altera_mf_ver -L altera_lnsim_ver -L stratixv_ver -L stratixv_hssi_ver -L stratixv_pcie_hip_ver -L rtl_work -L work -voptargs="+acc" testbench
|
||||
|
||||
add wave -group {dut} -radix hexadecimal sim:/testbench/dut/*
|
||||
|
||||
onfinish stop
|
||||
run -all
|
||||
|
||||
@@ -140,15 +140,6 @@ set_location_assignment PIN_C16 -to HEX0[3]
|
||||
|
||||
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
|
||||
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE addr_decode.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE bb_spi_controller.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE super6502.sv
|
||||
set_global_assignment -name QIP_FILE ram.qip
|
||||
set_global_assignment -name SDC_FILE super6502.sdc
|
||||
set_global_assignment -name QIP_FILE rom.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE HexDriver.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE SevenSeg.sv
|
||||
set_global_assignment -name QIP_FILE cpu_clk.qip
|
||||
set_location_assignment PIN_B8 -to rst_n
|
||||
set_location_assignment PIN_P11 -to clk_50
|
||||
set_global_assignment -name ENABLE_OCT_DONE OFF
|
||||
@@ -160,46 +151,45 @@ set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_vpb
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[15]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[14]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[13]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[12]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[11]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[10]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[9]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[8]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[7]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[6]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[5]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[4]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[3]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[2]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[1]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_addr[0]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_be
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_data[7]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_data[6]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_data[5]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_data[4]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_data[3]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_data[2]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_data[1]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_data[0]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_irqb
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_led
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_mlb
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_nmib
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_phi2
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_rdy
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_resb
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_rwb
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_sob
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to cpu_sync
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to clk_50
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_vpb
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[15]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[14]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[13]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[12]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[11]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[10]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[9]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[8]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[7]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[6]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[5]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[4]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[3]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[2]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[1]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_addr[0]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_be
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_data[7]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_data[6]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_data[5]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_data[4]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_data[3]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_data[2]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_data[1]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_data[0]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_irqb
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_led
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_mlb
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_nmib
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_phi2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_rdy
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_resb
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_rwb
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_sob
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to cpu_sync
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to clk_50
|
||||
set_global_assignment -name ENABLE_SIGNALTAP OFF
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE output_files/stp1.stp
|
||||
set_global_assignment -name SIGNALTAP_FILE output_files/stp1.stp
|
||||
set_location_assignment PIN_F20 -to HEX4[6]
|
||||
set_location_assignment PIN_F19 -to HEX4[5]
|
||||
set_location_assignment PIN_H19 -to HEX4[4]
|
||||
@@ -214,4 +204,83 @@ set_location_assignment PIN_N19 -to HEX5[5]
|
||||
set_location_assignment PIN_N20 -to HEX5[6]
|
||||
set_location_assignment PIN_F18 -to HEX4[0]
|
||||
set_location_assignment PIN_E20 -to HEX4[1]
|
||||
set_location_assignment PIN_AB5 -to UART_RXD
|
||||
set_location_assignment PIN_AB6 -to UART_TXD
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE uart.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE addr_decode.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE bb_spi_controller.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE super6502.sv
|
||||
set_global_assignment -name QIP_FILE ram.qip
|
||||
set_global_assignment -name SDC_FILE super6502.sdc
|
||||
set_global_assignment -name QIP_FILE rom.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE HexDriver.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE SevenSeg.sv
|
||||
set_global_assignment -name QIP_FILE cpu_clk.qip
|
||||
set_global_assignment -name SIGNALTAP_FILE output_files/stp1.stp
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to UART_RXD
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to UART_TXD
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[6]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[5]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[4]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[3]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[2]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[1]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX0[0]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[6]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[5]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[4]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[3]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[2]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[1]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX1[0]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[6]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[5]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[4]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[3]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[2]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[1]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX2[0]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[6]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[5]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[4]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[3]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[2]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[1]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX3[0]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX4[6]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX4[5]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX4[4]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX4[3]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX4[2]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX4[1]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX4[0]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX5[6]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX5[5]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX5[4]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX5[3]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX5[2]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX5[1]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to HEX5[0]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to rst_n
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[0]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[1]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[2]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[3]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[4]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[5]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[6]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[7]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[8]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to SW[9]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to Run
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[0]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[1]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[2]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[3]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[4]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[5]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[6]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[7]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[8]
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[9]
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@@ -20,7 +20,10 @@ module super6502(
|
||||
output logic cpu_be,
|
||||
output logic cpu_nmib,
|
||||
|
||||
output logic [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5
|
||||
output logic [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5,
|
||||
|
||||
input logic UART_RXD,
|
||||
output logic UART_TXD
|
||||
);
|
||||
|
||||
logic rst;
|
||||
@@ -37,10 +40,12 @@ assign cpu_data = cpu_rwb ? cpu_data_out : 'z;
|
||||
|
||||
logic [7:0] rom_data_out;
|
||||
logic [7:0] ram_data_out;
|
||||
logic [7:0] uart_data_out;
|
||||
|
||||
logic ram_cs;
|
||||
logic rom_cs;
|
||||
logic hex_cs;
|
||||
logic uart_cs;
|
||||
|
||||
cpu_clk cpu_clk(
|
||||
.inclk0(clk_50),
|
||||
@@ -62,7 +67,8 @@ addr_decode decode(
|
||||
.addr(cpu_addr),
|
||||
.ram_cs(ram_cs),
|
||||
.rom_cs(rom_cs),
|
||||
.hex_cs(hex_cs)
|
||||
.hex_cs(hex_cs),
|
||||
.uart_cs(uart_cs)
|
||||
);
|
||||
|
||||
|
||||
@@ -71,6 +77,8 @@ always_comb begin
|
||||
cpu_data_out = ram_data_out;
|
||||
else if (rom_cs)
|
||||
cpu_data_out = rom_data_out;
|
||||
else if (uart_cs)
|
||||
cpu_data_out = uart_data_out;
|
||||
else
|
||||
cpu_data_out = 'x;
|
||||
end
|
||||
@@ -102,7 +110,19 @@ SevenSeg segs(
|
||||
.addr(cpu_addr[1:0]),
|
||||
.HEX0(HEX0), .HEX1(HEX1), .HEX2(HEX2), .HEX3(HEX3), .HEX4(HEX4), .HEX5(HEX5)
|
||||
);
|
||||
|
||||
|
||||
uart uart(
|
||||
.clk_50(clk_50),
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.rw(cpu_rwb),
|
||||
.data_in(cpu_data_in),
|
||||
.cs(uart_cs),
|
||||
.addr(cpu_addr[1:0]),
|
||||
.RXD(UART_RXD),
|
||||
.TXD(UART_TXD),
|
||||
.data_out(uart_data_out)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
151
hw/fpga/uart.sv
Normal file
151
hw/fpga/uart.sv
Normal file
@@ -0,0 +1,151 @@
|
||||
module uart(
|
||||
input clk_50,
|
||||
input clk,
|
||||
input rst,
|
||||
|
||||
input cs,
|
||||
input rw,
|
||||
input [7:0] data_in,
|
||||
input [1:0] addr,
|
||||
|
||||
input RXD,
|
||||
|
||||
output logic TXD,
|
||||
|
||||
output logic [7:0] data_out
|
||||
);
|
||||
|
||||
//Handle reading and writing registers
|
||||
|
||||
logic [7:0] tx_buf;
|
||||
logic [7:0] rx_buf;
|
||||
logic [7:0] status;
|
||||
|
||||
logic tx_flag;
|
||||
|
||||
logic tx_flag_set;
|
||||
logic tx_flag_clear;
|
||||
|
||||
assign status[0] = tx_flag | tx_flag_clear;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (rst) begin
|
||||
tx_flag_set <= '0;
|
||||
tx_buf <= '0;
|
||||
rx_buf <= '0;
|
||||
status[7:1] <= '0;
|
||||
end
|
||||
|
||||
if (cs) begin
|
||||
if (~rw) begin
|
||||
if (addr == 0)
|
||||
tx_buf <= data_in;
|
||||
end else begin
|
||||
if (addr == 0)
|
||||
data_out <= rx_buf;
|
||||
if (addr == 1)
|
||||
data_out <= status;
|
||||
end
|
||||
end
|
||||
|
||||
if (~rw & cs && addr == 0)
|
||||
tx_flag_set <= '1;
|
||||
else
|
||||
tx_flag_set <= '0;
|
||||
end
|
||||
|
||||
// state controller
|
||||
typedef enum bit [2:0] {START, DATA, PARITY, STOP, IDLE} macro_t;
|
||||
struct packed {
|
||||
macro_t macro;
|
||||
logic [3:0] count;
|
||||
} state, next_state;
|
||||
localparam logic [3:0] maxcount = 4'h7;
|
||||
|
||||
// baud rate: 9600
|
||||
localparam baud = 9600;
|
||||
localparam count = (50000000/baud)-1;
|
||||
logic [14:0] clkdiv;
|
||||
|
||||
always_ff @(posedge clk_50) begin
|
||||
if (rst) begin
|
||||
clkdiv <= 0;
|
||||
state.macro <= IDLE;
|
||||
state.count <= 3'b0;
|
||||
tx_flag <= '0;
|
||||
end else begin
|
||||
if (tx_flag_set)
|
||||
tx_flag <= '1;
|
||||
else if (tx_flag_clear)
|
||||
tx_flag <= '0;
|
||||
|
||||
if (clkdiv == count) begin
|
||||
clkdiv <= 0;
|
||||
state <= next_state;
|
||||
end else begin
|
||||
clkdiv <= clkdiv + 15'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
next_state = state;
|
||||
|
||||
unique case (state.macro)
|
||||
START: begin
|
||||
next_state.macro = DATA;
|
||||
next_state.count = 3'b0;
|
||||
end
|
||||
DATA: begin
|
||||
if (state.count == maxcount) begin
|
||||
next_state.macro = STOP; // or PARITY
|
||||
next_state.count = 3'b0;
|
||||
end else begin
|
||||
next_state.count = state.count + 3'b1;
|
||||
next_state.macro = DATA;
|
||||
end
|
||||
end
|
||||
PARITY: begin
|
||||
end
|
||||
STOP: begin
|
||||
next_state.macro = IDLE;
|
||||
next_state.count = '0;
|
||||
end
|
||||
IDLE: begin
|
||||
if (tx_flag)
|
||||
next_state.macro = START;
|
||||
else
|
||||
next_state.macro = IDLE;
|
||||
end
|
||||
|
||||
default:;
|
||||
endcase
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
TXD = '1;
|
||||
tx_flag_clear = '0;
|
||||
|
||||
unique case (state.macro)
|
||||
START: begin
|
||||
TXD = '0;
|
||||
end
|
||||
DATA: begin
|
||||
TXD = tx_buf[state.count];
|
||||
end
|
||||
PARITY: begin
|
||||
|
||||
end
|
||||
STOP: begin
|
||||
tx_flag_clear = '1;
|
||||
TXD = '1;
|
||||
end
|
||||
IDLE: begin
|
||||
TXD = '1;
|
||||
end
|
||||
|
||||
default:;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -1 +1,6 @@
|
||||
SEVEN_SEG = $7ff0
|
||||
SEVEN_SEG = $7ff0
|
||||
|
||||
UART = $7ff4
|
||||
UART_TXB = UART
|
||||
UART_RXB = UART
|
||||
UART_STATUS = UART + 1
|
||||
|
||||
14
sw/main.c
14
sw/main.c
@@ -1,10 +1,24 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "sevenseg.h"
|
||||
#include "uart.h"
|
||||
|
||||
void puts(const char* s)
|
||||
{
|
||||
while (*s) {
|
||||
uart_txb_block(*s);
|
||||
if (*s == '\n')
|
||||
uart_txb_block('\r');
|
||||
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
hex_enable(0x3f);
|
||||
hex_set_24(0xabcdef);
|
||||
|
||||
puts("Hello, World!\n");
|
||||
while(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sevenseg.h"
|
||||
#include "uart.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
@@ -56,6 +57,23 @@ int main(void)
|
||||
}
|
||||
printf("Done!\n\n");
|
||||
|
||||
printf("Testing uart_txb_block...\n");
|
||||
*(uint8_t*)0x7ff5 = 0;
|
||||
uart_txb_block(0xa5);
|
||||
if (*(uint8_t*)0x7ff4 != 0xa5) {
|
||||
printf("Incorrect value!\n", i);
|
||||
retval++;
|
||||
}
|
||||
printf("Done!\n\n");
|
||||
|
||||
printf("Testing uart_status...\n");
|
||||
*(uint8_t*)0x7ff5 = 0xa5;
|
||||
if (uart_status() != 0xa5) {
|
||||
printf("Incorrect value!\n", i);
|
||||
retval++;
|
||||
}
|
||||
printf("Done!\n\n");
|
||||
|
||||
|
||||
return retval != 0;
|
||||
}
|
||||
11
sw/uart.h
Normal file
11
sw/uart.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef _UART_H
|
||||
#define _UART_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void uart_txb(uint8_t val);
|
||||
void uart_txb_block(uint8_t val);
|
||||
|
||||
uint8_t uart_status();
|
||||
|
||||
#endif
|
||||
29
sw/uart.s
Normal file
29
sw/uart.s
Normal file
@@ -0,0 +1,29 @@
|
||||
.include "io.inc65"
|
||||
|
||||
.importzp sp, sreg
|
||||
|
||||
.export _uart_txb
|
||||
.export _uart_txb_block
|
||||
.export _uart_status
|
||||
|
||||
.autoimport on
|
||||
|
||||
.code
|
||||
|
||||
; @in A: byte to transmit
|
||||
; Transmits a byte over the UART
|
||||
_uart_txb:
|
||||
sta UART_TXB ; Just write value, don't wait
|
||||
rts
|
||||
|
||||
_uart_txb_block:
|
||||
sta UART_TXB ; Write value
|
||||
@1: lda UART_STATUS ; Wait for status[0] to be 0
|
||||
bit #$01
|
||||
bne @1
|
||||
rts
|
||||
|
||||
_uart_status:
|
||||
lda UART_STATUS
|
||||
ldx #$00
|
||||
rts
|
||||
Reference in New Issue
Block a user