This commit is contained in:
WangXuan95 2022-04-07 17:12:33 +08:00
parent ce41504ca2
commit 7b3af4c460
147 changed files with 20065 additions and 27455 deletions

14
FPGA-Arty7/Arty7.xdc Normal file
View File

@ -0,0 +1,14 @@
## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_35 Sch=gclk[100]
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports { CLK100MHZ }];
##LEDs
set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L24N_T3_35 Sch=led[4]
set_property -dict { PACKAGE_PIN J5 IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_25_35 Sch=led[5]
set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_L24P_T3_A01_D17_14 Sch=led[6]
#set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L24N_T3_A00_D16_14 Sch=led[7]
##USB-UART Interface
set_property -dict { PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports { UART_TX }]; #IO_L19N_T3_VREF_16 Sch=uart_rxd_out
set_property -dict { PACKAGE_PIN A9 IOSTANDARD LVCMOS33 } [get_ports { UART_RX }]; #IO_L14N_T2_SRCC_16 Sch=uart_txd_in

View File

@ -0,0 +1,86 @@
module Arty7_USTCRVSoC_top(
input logic CLK100MHZ,
output logic [2:0] LED,
output logic UART_TX,
input logic UART_RX
);
logic clk; // 50MHz, SoC driving clock, generated by MMCM
// Show UART on LED2, LED1
assign LED[2:1] = ~{UART_RX, UART_TX};
//------------------------------------------------------------------------------------------------------
// SoC
//------------------------------------------------------------------------------------------------------
soc_top #(
.UART_RX_CLK_DIV ( 108 ), // 50MHz/4/115200 = 108
.UART_TX_CLK_DIV ( 434 ), // 50MHz/1/115200 = 434
.VGA_CLK_DIV ( 1 )
) soc_i (
.clk ( clk ),
.isp_uart_rx ( UART_RX ),
.isp_uart_tx ( UART_TX ),
.vga_hsync ( ),
.vga_vsync ( ),
.vga_red ( ),
.vga_green ( ),
.vga_blue ( )
);
//------------------------------------------------------------------------------------------------------
// MMCM primitive, generate SoC driving clock, equivalent to clock wizard IP
//------------------------------------------------------------------------------------------------------
wire clkin_buf, clkfb, clkfb_buf, clkout_unbuf;
BUFG bufg_clkin ( .O(clkin_buf), .I(CLK100MHZ) );
BUFG bufg_clkfb ( .O(clkfb_buf), .I(clkfb) );
BUFG bufg_clkout ( .O(clk), .I(clkout_unbuf) );
MMCME2_ADV #(
.BANDWIDTH ( "HIGH" ),
.CLKOUT4_CASCADE ( "FALSE" ),
.COMPENSATION ( "ZHOLD" ),
.STARTUP_WAIT ( "FALSE" ),
.DIVCLK_DIVIDE ( 1 ),
.CLKFBOUT_MULT_F ( 8.000 ), // f(clkfb) = f(clkin) * 8
.CLKFBOUT_PHASE ( 0.000 ),
.CLKFBOUT_USE_FINE_PS( "FALSE" ),
.CLKOUT0_DIVIDE_F ( 16.000 ), // f(clkout) = f(clkfb) / 16
.CLKOUT0_PHASE ( 0.000 ),
.CLKOUT0_DUTY_CYCLE ( 0.500 ),
.CLKOUT0_USE_FINE_PS ( "FALSE" ),
.CLKIN1_PERIOD ( 10.000 ) // T=10ns, f=100MHz
) mmcm_adv_i (
.CLKFBOUT ( clkfb ),
.CLKFBOUTB ( ),
.CLKOUT0 ( clkout_unbuf ),
.CLKOUT0B(), .CLKOUT1(), .CLKOUT1B(), .CLKOUT2(), .CLKOUT2B(), .CLKOUT3(), .CLKOUT3B(), .CLKOUT4(), .CLKOUT5(), .CLKOUT6(),
.CLKFBIN ( clkfb_buf ),
.CLKIN1 ( clkin_buf ),
.CLKIN2 ( 1'b0 ),
.CLKINSEL ( 1'b1 ),
.DADDR ( 7'h0 ),
.DCLK ( 1'b0 ),
.DEN ( 1'b0 ),
.DI ( 16'h0 ),
.DO ( ),
.DRDY ( ),
.DWE ( 1'b0 ),
.PSCLK ( 1'b0 ),
.PSEN ( 1'b0 ),
.PSINCDEC ( 1'b0 ),
.PSDONE ( ),
.LOCKED ( LED[0] ),
.CLKINSTOPPED ( ),
.CLKFBSTOPPED ( ),
.PWRDWN ( 1'b0 ),
.RST ( 1'b0 )
);
endmodule

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Product Version: Vivado v2018.3 (64-bit) -->
<!-- Product Version: Vivado v2019.1 (64-bit) -->
<!-- -->
<!-- Copyright 1986-2018 Xilinx, Inc. All Rights Reserved. -->
<!-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. -->
<Project Version="7" Minor="39" Path="E:/FPGAcommon/USTCRVSoC/hardware/Vivado/Arty7/USTCRVSoC-Arty7.xpr">
<Project Version="7" Minor="40" Path="E:/FPGAcommon/USTC-RVSoC/FPGA-Arty7/USTCRVSoC-Arty7.xpr">
<DefaultLaunch Dir="$PRUNDIR"/>
<Configuration>
<Option Name="Id" Val="c2573b9a7fc0486c86ecf427da721e59"/>
@ -59,146 +59,130 @@
<FileSets Version="1" Minor="31">
<FileSet Name="sources_1" Type="DesignSrcs" RelSrcDir="$PSRCDIR/sources_1">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/../../RTL/char8x16_rom.sv">
<File Path="$PPRDIR/../RTL/cpu/core_alu.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_alu.sv">
<File Path="$PPRDIR/../RTL/cpu/core_bus_wrapper.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_bus_wrapper.sv">
<File Path="$PPRDIR/../RTL/cpu/core_id_stage.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_id_stage.sv">
<File Path="$PPRDIR/../RTL/cpu/core_instr_bus_adapter.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_instr_bus_adapter.sv">
<File Path="$PPRDIR/../RTL/cpu/core_regfile.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_regfile.sv">
<File Path="$PPRDIR/../RTL/cpu/core_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_top.sv">
<File Path="$PPRDIR/../RTL/instr_rom.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/dual_read_port_ram_32x32.sv">
<File Path="$PPRDIR/../RTL/uart/isp_uart.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/instr_rom.sv">
<File Path="$PPRDIR/../RTL/naive_bus.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/isp_uart.sv">
<File Path="$PPRDIR/../RTL/naive_bus_router.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/naive_bus.sv">
<File Path="$PPRDIR/../RTL/ram.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/naive_bus_router.sv">
<File Path="$PPRDIR/../RTL/ram_bus_wrapper.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/ram.sv">
<File Path="$PPRDIR/../RTL/soc_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/ram128B.sv">
<File Path="$PPRDIR/../RTL/uart/uart_rx.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/ram_bus_wrapper.sv">
<File Path="$PPRDIR/../RTL/uart/uart_tx_line.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/soc_top.sv">
<File Path="$PPRDIR/../RTL/uart/user_uart_tx.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/uart_rx.sv">
<File Path="$PPRDIR/../RTL/vga_char_86x32.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/uart_tx_line.sv">
<File Path="$PPRDIR/../RTL/video_ram.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/user_uart_tx.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/vga_char_86x32.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/video_ram.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sources_1/new/Arty7_USTCRVSoC_top.sv">
<File Path="$PPRDIR/Arty7_USTCRVSoC_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="Arty7_USTCRVSoC_top"/>
<Option Name="TopAutoSet" Val="TRUE"/>
</Config>
</FileSet>
<FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1">
<Filter Type="Constrs"/>
<File Path="$PSRCDIR/constrs_1/new/Arty7.xdc">
<File Path="$PPRDIR/Arty7.xdc">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -209,8 +193,11 @@
</Config>
</FileSet>
<FileSet Name="sim_1" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sim_1">
<Filter Type="Srcs"/>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="Arty7_USTCRVSoC_top"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TopAutoSet" Val="TRUE"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
@ -245,9 +232,7 @@
<Runs Version="1" Minor="10">
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7a35ticsg324-1L" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/synth_1" IncludeInArchive="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2018">
<Desc>Vivado Synthesis Defaults</Desc>
</StratHandle>
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2018"/>
<Step Id="synth_design"/>
</Strategy>
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
@ -256,9 +241,7 @@
</Run>
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a35ticsg324-1L" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/impl_1" SynthRun="synth_1" IncludeInArchive="true" GenFullBitstream="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2018">
<Desc>Default settings for Implementation.</Desc>
</StratHandle>
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2018"/>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
@ -305,6 +288,28 @@
</Dashboards>
</DashboardSummary>
<BootPmcSettings Version="1" Minor="0">
<Parameters/>
<Parameters>
<Parameter Name="PMC_CDO.ATTRS.LOADADDR" Value="" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_FB_CLK" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_FREQ" Value="300" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_BUS_WIDTH" Value="x1" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_DATA_MODE" Value="Single" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_FREQ" Value="200" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_SLOT_TYPE" Value="SD 2.0" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_DATA_TRANSFER_MODE" Value="4Bit" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_FREQ" Value="200" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_SLOT_TYPE" Value="SD 2.0" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_DATA_TRANSFER_MODE" Value="4Bit" Type="string"/>
<Parameter Name="BOOT.PMC.OSPI_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.OSPI_FREQ" Value="300" Type="string"/>
<Parameter Name="BOOT.USB_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SMAP_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SMAP_DATA_WIDTH" Value="32 Bit" Type="string"/>
<Parameter Name="BOOT.PMC.OSC_FREQ" Value="33.333" Type="string"/>
<Parameter Name="BOOT.SECONDARY.PCIE_ENABLE" Value="0" Type="string"/>
</Parameters>
</BootPmcSettings>
</Project>

View File

@ -239,7 +239,7 @@ set_global_assignment -name DEVICE EP4CE22F17C6
set_global_assignment -name TOP_LEVEL_ENTITY DE0Nano_USTCRVSoC_top
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_CREATION_TIME_DATE "22:31:13 MARCH 02, 2019"
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Standard Edition"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
@ -260,26 +260,25 @@ set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name FLOW_DISABLE_ASSEMBLER OFF
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
set_global_assignment -name SYSTEMVERILOG_FILE DE0Nano_USTCRVSoC_top.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/naive_bus.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/naive_bus_router.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/soc_top.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/isp_uart.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/user_uart_tx.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/uart_tx_line.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/uart_rx.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/instr_rom.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/ram_bus_wrapper.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/ram.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/video_ram.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/vga_char_86x32.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/char8x16_rom.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/ram128B.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_top.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_regfile.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_instr_bus_adapter.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_id_stage.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_alu.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_bus_wrapper.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/dual_read_port_ram_32x32.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/soc_top.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/naive_bus.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/naive_bus_router.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/instr_rom.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/ram_bus_wrapper.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/ram.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/video_ram.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/vga_char_86x32.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/uart/isp_uart.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/uart/user_uart_tx.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/uart/uart_tx_line.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/uart/uart_rx.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/cpu/core_top.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/cpu/core_regfile.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/cpu/core_instr_bus_adapter.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/cpu/core_id_stage.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/cpu/core_alu.sv
set_global_assignment -name SYSTEMVERILOG_FILE ../RTL/cpu/core_bus_wrapper.sv
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top

View File

@ -1,19 +1,22 @@
module DE0Nano_USTCRVSoC_top(
//////////// CLOCK //////////
input CLOCK_50,
input CLOCK_50,
//////////// LED, KEY, Switch //////////
output [ 7:0] LED,
//////////// GPIO Header 1 //////////
input [ 1:0] GPIO_0_IN,
inout [33:0] GPIO_0,
input [ 1:0] GPIO_1_IN,
inout [33:0] GPIO_1
output [33:0] GPIO_0,
input [ 0:0] GPIO_1_IN,
output [ 0:0] GPIO_1
);
logic vga_red, vga_green, vga_blue;
assign GPIO_0[31:16] = {{5{vga_blue}},{6{vga_green}},{5{vga_red}}};
soc_top soc_inst(
soc_top #(
.UART_RX_CLK_DIV ( 108 ), // 50MHz/4/115200 = 108
.UART_TX_CLK_DIV ( 434 ), // 50MHz/1/115200 = 434
.VGA_CLK_DIV ( 1 )
) soc_i (
.clk ( CLOCK_50 ),
.isp_uart_rx ( GPIO_1_IN[0] ),
.isp_uart_tx ( GPIO_1[0] ),
@ -25,10 +28,10 @@ soc_top soc_inst(
);
// 在开发板的LED上显示ISP-UART和USER-UART的发送灯和接收灯
assign LED[7:6] = ~{GPIO_1_IN[0],GPIO_1[0]};
assign LED[7:6] = ~{GPIO_1_IN[0], GPIO_1[0]};
// VGA GND
assign GPIO_0[12] = 1'b0;
assign GPIO_0[15:0] = 16'b0;
// 流水灯指示SoC在运行
reg [21:0] cnt = 22'h0;

42
FPGA-Nexys4/Nexys4.xdc Normal file
View File

@ -0,0 +1,42 @@
## Clock signal
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { CLK100MHZ }]; #IO_L12P_T1_MRCC_35 Sch=clk100mhz
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {CLK100MHZ}];
## LEDs
set_property -dict { PACKAGE_PIN H17 IOSTANDARD LVCMOS33 } [get_ports { LED[0] }]; #IO_L18P_T2_A24_15 Sch=led[0]
set_property -dict { PACKAGE_PIN K15 IOSTANDARD LVCMOS33 } [get_ports { LED[1] }]; #IO_L24P_T3_RS1_15 Sch=led[1]
set_property -dict { PACKAGE_PIN J13 IOSTANDARD LVCMOS33 } [get_ports { LED[2] }]; #IO_L17N_T2_A25_15 Sch=led[2]
#set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { LED[3] }]; #IO_L8P_T1_D11_14 Sch=led[3]
#set_property -dict { PACKAGE_PIN R18 IOSTANDARD LVCMOS33 } [get_ports { LED[4] }]; #IO_L7P_T1_D09_14 Sch=led[4]
#set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { LED[5] }]; #IO_L18N_T2_A11_D27_14 Sch=led[5]
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { LED[6] }]; #IO_L17P_T2_A14_D30_14 Sch=led[6]
#set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { LED[7] }]; #IO_L18P_T2_A12_D28_14 Sch=led[7]
#set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { LED[8] }]; #IO_L16N_T2_A15_D31_14 Sch=led[8]
#set_property -dict { PACKAGE_PIN T15 IOSTANDARD LVCMOS33 } [get_ports { LED[9] }]; #IO_L14N_T2_SRCC_14 Sch=led[9]
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { LED[10] }]; #IO_L22P_T3_A05_D21_14 Sch=led[10]
#set_property -dict { PACKAGE_PIN T16 IOSTANDARD LVCMOS33 } [get_ports { LED[11] }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 Sch=led[11]
#set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { LED[12] }]; #IO_L16P_T2_CSI_B_14 Sch=led[12]
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { LED[13] }]; #IO_L22N_T3_A04_D20_14 Sch=led[13]
#set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { LED[14] }]; #IO_L20N_T3_A07_D23_14 Sch=led[14]
#set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { LED[15] }]; #IO_L21N_T3_DQS_A06_D22_14 Sch=led[15]
##VGA Connector
set_property -dict { PACKAGE_PIN A3 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[0] }]; #IO_L8N_T1_AD14N_35 Sch=vga_r[0]
set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[1] }]; #IO_L7N_T1_AD6N_35 Sch=vga_r[1]
set_property -dict { PACKAGE_PIN C5 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[2] }]; #IO_L1N_T0_AD4N_35 Sch=vga_r[2]
set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { VGA_R[3] }]; #IO_L8P_T1_AD14P_35 Sch=vga_r[3]
set_property -dict { PACKAGE_PIN C6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[0] }]; #IO_L1P_T0_AD4P_35 Sch=vga_g[0]
set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[1] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=vga_g[1]
set_property -dict { PACKAGE_PIN B6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[2] }]; #IO_L2N_T0_AD12N_35 Sch=vga_g[2]
set_property -dict { PACKAGE_PIN A6 IOSTANDARD LVCMOS33 } [get_ports { VGA_G[3] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=vga_g[3]
set_property -dict { PACKAGE_PIN B7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[0] }]; #IO_L2P_T0_AD12P_35 Sch=vga_b[0]
set_property -dict { PACKAGE_PIN C7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[1] }]; #IO_L4N_T0_35 Sch=vga_b[1]
set_property -dict { PACKAGE_PIN D7 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[2] }]; #IO_L6N_T0_VREF_35 Sch=vga_b[2]
set_property -dict { PACKAGE_PIN D8 IOSTANDARD LVCMOS33 } [get_ports { VGA_B[3] }]; #IO_L4P_T0_35 Sch=vga_b[3]
set_property -dict { PACKAGE_PIN B11 IOSTANDARD LVCMOS33 } [get_ports { VGA_HS }]; #IO_L4P_T0_15 Sch=vga_hs
set_property -dict { PACKAGE_PIN B12 IOSTANDARD LVCMOS33 } [get_ports { VGA_VS }]; #IO_L3N_T0_DQS_AD1N_15 Sch=vga_vs
##USB-RS232 Interface
set_property -dict { PACKAGE_PIN C4 IOSTANDARD LVCMOS33 } [get_ports { UART_RX }]; #IO_L7P_T1_AD6P_35 Sch=uart_txd_in
set_property -dict { PACKAGE_PIN D4 IOSTANDARD LVCMOS33 } [get_ports { UART_TX }]; #IO_L11N_T1_SRCC_35 Sch=uart_rxd_out

View File

@ -0,0 +1,95 @@
module Nexys4_USTCRVSoC_top(
input logic CLK100MHZ,
output logic [2:0] LED,
output logic UART_TX,
input logic UART_RX,
output logic VGA_HS, VGA_VS,
output logic [3:0] VGA_R, VGA_G, VGA_B
);
logic clk; // 50MHz, SoC driving clock, generated by MMCM
// Show UART on LED2, LED1
assign LED[2:1] = ~{UART_RX, UART_TX};
// VGA assignment
logic vga_red, vga_green, vga_blue;
assign VGA_R = {4{vga_red}};
assign VGA_G = {4{vga_green}};
assign VGA_B = {4{vga_blue}};
//------------------------------------------------------------------------------------------------------
// SoC
//------------------------------------------------------------------------------------------------------
soc_top #(
.UART_RX_CLK_DIV ( 108 ), // 50MHz/4/115200 = 108
.UART_TX_CLK_DIV ( 434 ), // 50MHz/1/115200 = 434
.VGA_CLK_DIV ( 1 )
) soc_i (
.clk ( clk ),
.isp_uart_rx ( UART_RX ),
.isp_uart_tx ( UART_TX ),
.vga_hsync ( VGA_HS ),
.vga_vsync ( VGA_VS ),
.vga_red ( vga_red ),
.vga_green ( vga_green ),
.vga_blue ( vga_blue )
);
//------------------------------------------------------------------------------------------------------
// MMCM primitive, generate SoC driving clock, equivalent to clock wizard IP
//------------------------------------------------------------------------------------------------------
wire clkin_buf, clkfb, clkfb_buf, clkout_unbuf;
BUFG bufg_clkin ( .O(clkin_buf), .I(CLK100MHZ) );
BUFG bufg_clkfb ( .O(clkfb_buf), .I(clkfb) );
BUFG bufg_clkout ( .O(clk), .I(clkout_unbuf) );
MMCME2_ADV #(
.BANDWIDTH ( "HIGH" ),
.CLKOUT4_CASCADE ( "FALSE" ),
.COMPENSATION ( "ZHOLD" ),
.STARTUP_WAIT ( "FALSE" ),
.DIVCLK_DIVIDE ( 1 ),
.CLKFBOUT_MULT_F ( 8.000 ), // f(clkfb) = f(clkin) * 8
.CLKFBOUT_PHASE ( 0.000 ),
.CLKFBOUT_USE_FINE_PS( "FALSE" ),
.CLKOUT0_DIVIDE_F ( 16.000 ), // f(clkout) = f(clkfb) / 16
.CLKOUT0_PHASE ( 0.000 ),
.CLKOUT0_DUTY_CYCLE ( 0.500 ),
.CLKOUT0_USE_FINE_PS ( "FALSE" ),
.CLKIN1_PERIOD ( 10.000 ) // T=10ns, f=100MHz
) mmcm_adv_i (
.CLKFBOUT ( clkfb ),
.CLKFBOUTB ( ),
.CLKOUT0 ( clkout_unbuf ),
.CLKOUT0B(), .CLKOUT1(), .CLKOUT1B(), .CLKOUT2(), .CLKOUT2B(), .CLKOUT3(), .CLKOUT3B(), .CLKOUT4(), .CLKOUT5(), .CLKOUT6(),
.CLKFBIN ( clkfb_buf ),
.CLKIN1 ( clkin_buf ),
.CLKIN2 ( 1'b0 ),
.CLKINSEL ( 1'b1 ),
.DADDR ( 7'h0 ),
.DCLK ( 1'b0 ),
.DEN ( 1'b0 ),
.DI ( 16'h0 ),
.DO ( ),
.DRDY ( ),
.DWE ( 1'b0 ),
.PSCLK ( 1'b0 ),
.PSEN ( 1'b0 ),
.PSINCDEC ( 1'b0 ),
.PSDONE ( ),
.LOCKED ( LED[0] ),
.CLKINSTOPPED ( ),
.CLKFBSTOPPED ( ),
.PWRDWN ( 1'b0 ),
.RST ( 1'b0 )
);
endmodule

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Product Version: Vivado v2018.3 (64-bit) -->
<!-- Product Version: Vivado v2019.1 (64-bit) -->
<!-- -->
<!-- Copyright 1986-2018 Xilinx, Inc. All Rights Reserved. -->
<!-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. -->
<Project Version="7" Minor="39" Path="E:/FPGAcommon/USTCRVSoC/hardware/Vivado/Nexys4/USTCRVSoC-nexys4.xpr">
<Project Version="7" Minor="40" Path="E:/FPGAcommon/USTC-RVSoC/FPGA-Nexys4/USTCRVSoC-nexys4.xpr">
<DefaultLaunch Dir="$PRUNDIR"/>
<Configuration>
<Option Name="Id" Val="ddc8340f1eba4b8bbb076a11b9b82028"/>
@ -56,133 +56,119 @@
<FileSets Version="1" Minor="31">
<FileSet Name="sources_1" Type="DesignSrcs" RelSrcDir="$PSRCDIR/sources_1">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/../../RTL/char8x16_rom.sv">
<File Path="$PPRDIR/../RTL/cpu/core_alu.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_alu.sv">
<File Path="$PPRDIR/../RTL/cpu/core_bus_wrapper.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_bus_wrapper.sv">
<File Path="$PPRDIR/../RTL/cpu/core_id_stage.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_id_stage.sv">
<File Path="$PPRDIR/../RTL/cpu/core_instr_bus_adapter.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_instr_bus_adapter.sv">
<File Path="$PPRDIR/../RTL/cpu/core_regfile.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_regfile.sv">
<File Path="$PPRDIR/../RTL/cpu/core_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_top.sv">
<File Path="$PPRDIR/../RTL/instr_rom.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/dual_read_port_ram_32x32.sv">
<File Path="$PPRDIR/../RTL/uart/isp_uart.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../RTL/naive_bus.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/instr_rom.sv">
<File Path="$PPRDIR/../RTL/naive_bus_router.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/isp_uart.sv">
<File Path="$PPRDIR/../RTL/ram.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/naive_bus.sv">
<File Path="$PPRDIR/../RTL/ram_bus_wrapper.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/naive_bus_router.sv">
<File Path="$PPRDIR/../RTL/soc_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/ram.sv">
<File Path="$PPRDIR/../RTL/uart/uart_rx.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../RTL/uart/uart_tx_line.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../RTL/uart/user_uart_tx.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../RTL/vga_char_86x32.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/ram128B.sv">
<File Path="$PPRDIR/../RTL/video_ram.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/ram_bus_wrapper.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/soc_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/uart_rx.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/uart_tx_line.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/user_uart_tx.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/vga_char_86x32.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/video_ram.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sources_1/Nexys4_USTCRVSoC_top.sv">
<File Path="$PPRDIR/Nexys4_USTCRVSoC_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -195,7 +181,7 @@
</FileSet>
<FileSet Name="constrs_1" Type="Constrs" RelSrcDir="$PSRCDIR/constrs_1">
<Filter Type="Constrs"/>
<File Path="$PSRCDIR/constrs_1/Nexys-A7-100T-Master.xdc">
<File Path="$PPRDIR/Nexys4.xdc">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -209,6 +195,8 @@
<Filter Type="Srcs"/>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="isp_uart"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TopAutoSet" Val="TRUE"/>
<Option Name="TransportPathDelay" Val="0"/>
<Option Name="TransportIntDelay" Val="0"/>
@ -250,7 +238,7 @@
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2017"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
</Run>
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a100tcsg324-1" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" Dir="$PRUNDIR/impl_1" SynthRun="synth_1" IncludeInArchive="true" GenFullBitstream="true">
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a100tcsg324-1" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" SynthRun="synth_1" IncludeInArchive="true" GenFullBitstream="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2017"/>
<Step Id="init_design"/>
@ -263,7 +251,6 @@
<Step Id="post_route_phys_opt_design"/>
<Step Id="write_bitstream"/>
</Strategy>
<GeneratedRun Dir="$PRUNDIR" File="gen_run.xml"/>
<ReportStrategy Name="Vivado Implementation Default Reports" Flow="Vivado Implementation 2017"/>
<Report Name="ROUTE_DESIGN.REPORT_METHODOLOGY" Enabled="1"/>
</Run>
@ -299,6 +286,28 @@
</Dashboards>
</DashboardSummary>
<BootPmcSettings Version="1" Minor="0">
<Parameters/>
<Parameters>
<Parameter Name="PMC_CDO.ATTRS.LOADADDR" Value="" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_FB_CLK" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_FREQ" Value="300" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_BUS_WIDTH" Value="x1" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_DATA_MODE" Value="Single" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_FREQ" Value="200" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_SLOT_TYPE" Value="SD 2.0" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_DATA_TRANSFER_MODE" Value="4Bit" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_FREQ" Value="200" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_SLOT_TYPE" Value="SD 2.0" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_DATA_TRANSFER_MODE" Value="4Bit" Type="string"/>
<Parameter Name="BOOT.PMC.OSPI_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.OSPI_FREQ" Value="300" Type="string"/>
<Parameter Name="BOOT.USB_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SMAP_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SMAP_DATA_WIDTH" Value="32 Bit" Type="string"/>
<Parameter Name="BOOT.PMC.OSC_FREQ" Value="33.333" Type="string"/>
<Parameter Name="BOOT.SECONDARY.PCIE_ENABLE" Value="0" Type="string"/>
</Parameters>
</BootPmcSettings>
</Project>

605
README.md
View File

@ -1,285 +1,320 @@
![语言](https://img.shields.io/badge/语言-systemverilog_(IEEE1800_2005)-CAD09D.svg) ![仿真](https://img.shields.io/badge/仿真-vivado-FF1010.svg) ![部署](https://img.shields.io/badge/部署-vivado-FF1010.svg) ![部署](https://img.shields.io/badge/部署-quartus-blue.svg)
USTCRVSoC
===========================
一个用 SystemVerilog 编写的,基于 RISC-V 的,普林斯顿结构的 SoC
****
## 目录
* [特点](#特点)
* [SoC结构](#SoC结构)
* [CPU特性](#CPU特性)
* [部署到FPGAf](#部署到FPGA)
* 部署到 Nexys4
* 部署到 Arty7
* 部署到 DE0-Nano
* 部署到其它开发板
* [测试软件](#测试软件)
* Hello World
* 使用 UART 调试总线
* 使用 VGA 屏幕
* 使用工具USTCRVSoC-tool
* [CPU仿真](#CPU仿真)
* 进行仿真
* [SoC仿真](#SoC仿真)
* 进行仿真
* 修改指令ROM
# 特点
* **CPU**5段流水线 RISC-V ,能运行 **RV32I** 指令集中的大部分指令
* **总线**:简单的具有**握手机制**的32-bit地址位宽和32-bit数据位宽的总线
* **总线交叉开关 (bus router)**:可使用参数修改总线主从接口的数量和从接口占用的地址空间,以方便拓展外设
* **交互式 UART 调试**支持使用PC上的Putty、串口助手、minicom等软件实现**系统复位**、**上传程序**、**查看内存**等功能
* 完全使用 SystemVerilog 实现不调用IP核便于移植和仿真
# SoC结构
![SoC结构框图](./images/SoC.png)
上图展示了SoC的结构总线仲裁器 **bus_router** 也叫总线交叉开关为SoC的中心上面挂载了3个**主接口**和5个**从接口**。这个SoC使用的总线并不来自于任何标准例如AXI或APB总线而是笔者自编的因为简单所以命名为**naive_bus**。
每个**从接口**都占有一段地址空间。当**主接口**访问总线时,**bus_router**判断该地址属于哪个地址空间,然后将它**路由**到相应的**从接口**。下表展示了5个**从接口**的地址空间。
| 外设类型 | 起始地址 | 结束地址 |
| :-----: | :-----: | :----: |
| 指令ROM | 0x00000000 | 0x00007fff |
| 指令RAM | 0x00008000 | 0x00008fff |
| 数据RAM | 0x00010000 | 0x00010fff |
| 显存RAM | 0x00020000 | 0x00020fff |
| 用户UART | 0x00030000 | 0x00030003 |
### 组成部件
* **多主多从总线仲裁器 (bus_router)**:对应文件 naive_bus_router.sv。为每个从设备划分地址空间将主设备的总线读写请求路由到从设备。当多个主设备同时访问一个从设备时还能根据主设备的优先级进行冲突仲裁。
* **RV32I Core**:对应文件 core_top.sv。包括两个主接口。一个用于取指令一个用于读写数据。
* **UART调试器**:对应文件 isp_uart.sv。将UART调试功能和用户UART结合为一体。包括一个主接口和一个从接口。它接收上位机从UART发来的命令对总线进行读写。它可以用于在线烧写、在线调试。也可以接收CPU的命令去发送数据给用户。
* **指令ROM**:对应文件 instr_rom.sv。CPU默认从这里开始取指令里面的指令流是在硬件代码编译综合时就固定的不能在运行时修改。唯一的修改方法是编辑 **instr_rom.sv** 中的代码然后重新编译综合、烧写FPGA逻辑。因此**instr_rom** 多用于仿真。
* **指令RAM**:对应文件 ram_bus_wrapper.sv。用户使用 isp_uart 在线烧写指令流到这里,然后将 Boot 地址指向这里再复位SoC后CPU就从这里开始运行指令流。
* **数据RAM**:对应文件 ram_bus_wrapper.sv。存放运行时的数据。
* **显存RAM**:对应文件 video_ram.sv。在屏幕上显示 86列 * 32行 = 2752 个字符,显存 RAM 的 4096B 被划分为 32 个块,每块对应一行,占 128B前 86 字节对应 86 个列。屏幕上显示的是每个字节作为 ASCII 码所对应的字符。
# CPU特性
* 支持: **RV32I** 中的所有Load、Store、算术、逻辑、移位、比较、跳转。
* 不支持:同步、控制状态、环境调用和断点类指令
所有支持的指令包括:
> LB, LH, LW, LBU, LHU, SB, SH, SW, ADD, ADDI, SUB, LUI, AUIPC, XOR, XORI, OR, ORI, AND, ANDI, SLL, SLLI, SRL, SRLI, SRA, SRAI, SLT, SLTI, SLTU, SLTIU, BEQ, BNE, BLT ,BGE, BLTU, BGEU, JAL, JALR
指令集方面,今后可能先考虑加入 **RV32IM** 中的乘除指令。
CPU采用5段流水线目前支持的流水线特性有
> Forward、Loaduse、总线握手等待
流水线方面,今后考虑添加的特性有:
> 分支预测、中断
# 部署到FPGA
目前,我们提供了 Xilinx 的 **Nexys4 开发板****Arty7 开发板** 和 Altera 的 **DE0-Nano 开发板** 的工程。
为了进行部署和测试,你需要准备以下的东西:
* 装有 **Windows7 系统** 或更高版本的 PC如果使用 Linux 则很难用上我提供的几个C#编写的工具
* **Nexys4 开发板****Arty7 开发板****DE0-Nano 开发板** 或其它 FPGA 开发板
* 开发板对应的 **RTL 开发环境**,例如 **Nexys4 开发板****Arty7 开发板** 对应 Vivado推荐 Vivado 2018.3 或更高版本DE0-Nano 对应 Quartus 推荐Quartus II 13.1 或更高版本)
* 如果你的开发板没有自带 **USB转UART** 电路(例如 DE0-Nano则需要一个 **USB转UART模块**
* **可选***屏幕、VGA线*
## 部署到 Nexys4
![Nexys4照片](./images/nexys4-connection2.png)
1. **硬件连接**如上图Nexys4 开发板上有一个 USB 口,既可以用于 FPGA 烧录,也可以用于 UART 通信,我们需要连接该 USB 口到电脑。另外VGA 的连接是可选的,你可以把它连接到屏幕上。
2. **综合、烧写**:请用 Vivado 打开 **./hardware/Vivado/Nexys4/USTCRVSoC-nexys4.xpr**。综合并烧写到开发板。
## 部署到 Arty7
1. **硬件连接**Arty7 开发板上有一个 USB 口,既可以用于 FPGA 烧录,也可以用于 UART 通信,我们需要连接该 USB 口到电脑。
2. **综合、烧写**:请用 Vivado 打开 **./hardware/Vivado/Arty7/USTCRVSoC-Arty7.xpr**。综合并烧写到开发板。
## 部署到 DE0-Nano
![DE0Nano照片](./images/DE0-Nano.png)
1、**硬件连接**DE0-Nano开发板上既没有串口转USB也没有VGA接口。因此需要外部模块以及一些动手能力和硬件知识。我们使用DE0-Nano上的两排GPIO作为外接模块的引脚接口意义如上图。你需要一个USB转UART的模块将UART的TX和RX引脚连接上去使之能与电脑通信。VGA的连接是可选的需要符合上图中VGA的引脚定义。最后连接的效果如下图
![DE0Nano照片连接](./images/connection.png)
2、**综合、烧写**:请用 Quartus 打开 **./hardware/Quartus/DE0_Nano/DE0_Nano.qpf**。综合并烧写到开发板。
## 部署到其它开发板
如果很不幸,你手头的 FPGA 开发板不是上述开发板,则需要手动建立工程,连接信号到开发板顶层。分为以下步骤:
* **建立工程**:建立工程后,需要将 **./hardware/RTL/** 中的所有 .sv 文件添加进工程。
* **编写顶层**SoC 的顶层文件是 **./hardware/RTL/soc_top.sv**,你需要编写一个针对该开发板的顶层文件,调用 **soc_top**,并将 FPGA 的引脚连接到 **soc_top** 中。以下是对 **soc_top** 的信号说明。
* **编译、综合、烧写到FPGA**
```Verilog
module soc_top #(
// UART接收分频系数请根据clk的时钟频率决定计算公式 UART_RX_CLK_DIV=clk频率(Hz)/460800四舍五入
parameter UART_RX_CLK_DIV = 108,
// UART发送分频系数请根据clk的时钟频率决定计算公式 UART_TX_CLK_DIV=clk频率(Hz)/115200四舍五入
parameter UART_TX_CLK_DIV = 434,
// VGA分频系数请根据clk的时钟频率决定计算公式 VGA_CLK_DIV=clk频率(Hz)/50000000
parameter VGA_CLK_DIV = 1
)(
input logic clk, // SoC 时钟,推荐使用 50MHz 的倍数
input logic isp_uart_rx, // 连接到开发板的 UART RX 引脚
output logic isp_uart_tx, // 连接到开发板的 UART TX 引脚
output logic vga_hsync, vga_vsync, // 连接到VGA可以不连接
output logic vga_red, vga_green, vga_blue // 连接到VGA可以不连接
);
```
# 测试软件
硬件烧写后,开始对它进行测试
### 查看 Hello World
硬件烧写后,如果你的开发板上有 UART 指示灯,就已经能看到 TX 指示灯在闪烁,每闪烁一下其实是在发送一个"Hello"这说明CPU在运行指令ROM里默认的程序。下面我们来查看这个Hello。
首先我们需要一款**串口终端软件**,例如:
* minicom
* 串口助手
* 超级终端
* Putty
这些工具用起来都不够爽快,因此这里使用该仓库中自带的小工具 **UartSession** 做示范。它的路径是 **./tools/UartSession.exe**。
> **UartSession** 使用C#编写 **./UartSession-VS2012** 中有 VisualStudio 工程。
首先,我们运行 **UartSession.exe**,可以看到该软件将电脑的所有可用端口都列了出来,并给出了几个选项:
* **打开端口**:输入数字,按回车可以打开数字对应的端口。
* **修改波特率**:输入"baud [数字]"再按回车可以修改波特率。例如输入baud 9600可以修改波特率为9600。
* **刷新端口列表**:输入"refresh",再按回车可以刷新端口列表。
* **退出**:输入"exit"可以退出
![UartSession](./images/UartSession2.png)
波特率默认是115200与我们的 SoC 一致,不需要修改。直接从端口列表里找到 FPGA 开发板所对应的端口,打开它。我们就可以看到窗口中不断显示"hello"根本停不下来如上图这说明CPU在正常运行程序。
> 如果不知道端口列表中哪个端口对应 FPGA 开发板,可以拔下开发板的 USB刷新一次端口列表则消失的端口就是开发板对应的端口。然后再插上USB如果FPGA内的电路丢失则需要重新烧录FPGA
### 使用 UART 调试总线
现在界面中不断地打印出"hello",我们打一个回车,可以看到对方不再打出"hello",并出现了一个"debug",这样就成功进入了 **DEBUG模式**
![UartSession](./images/UartSession1.png)
UART 调试器有两种模式:
* **USER 模式**:该模式下可以收到 CPU 通过 isp_uart 发送的用户打印数据。FPGA烧写后默认处于这个模式。hello只有在这个模式下才能被我们看到。通过向 uart **发送一个\n** 可以跳出 **USER模式**进入DEBUG模式。
* **DEBUG 模式**:该模式下 CPU 打印的任何数据都会被抑制UART 不再主动发送数据,变成了**一问一答**的形式,用户发送的调试命令和接收到的应答都**以\n结尾**,通过发送"o"或系统复位可以回到 **USER模式**
下面让我们尝试 **UART 的调试功能**,输入 **"0"** 并按回车会看到对方发来一个8位16进制数。该数就是SoC总线的地址 0x00000000 处读取出的数据,也就是**指令ROM**中的第一个指令,如下图。
![UartSession](./images/UartSession3.png)
除了读,我们也可以用调试器写总线,输入一条写命令: "10000 abcd1234" 并按回车,会看到对方发来 **"wr done"** ,意为写成功,该命令意为向地址 0x10000 中写入 0xabcd1234 (0x10000是数据RAM的首地址
为了验证写成功,输入读指令:**"10000"** 并按回车,会看到对方发来**"abcd1234"**。
> 注UART 调试器每次读写总线只能以**4字节对齐**的形式并且一次必须读写4字节。
下表显示了 **DEBUG模式** 的所有命令格式。
| 命令类型 | 命令示例 | 返回示例 | 含义 |
| ----- | :----- | :---- | :----- |
| 读总线 | 00020000 | abcd1234 | 地址0x00020000读出的数据是0xabcd1234 |
| 写总线 | 00020004 1276acd0 | wr done | 向地址0x00020004写数据0x1276acd0 |
| 切至USER模式 | o | user | 切换回USER模式
| 复位 | r00008000 | rst done | CPU 复位并从地址 0x00008000 处开始执行,同时切换回 USER 模式 |
| 非法命令 | ^^$aslfdi | invalid | 发送的指令未定义 |
> 注:无论是发送还是接收,所有命令都以\n或\r或\r\n结尾**UartSession.exe**是自动插入\n的。如果使用串口助手等其它软件需要注意这个问题。
根据这些命令,不难猜出,在线上传程序的流程是:
1. 使用写命令,将指令流写入指令 RAM ,(指令 RAM 的地址是 00008000~00008fff
2. 使用复位命令 r00008000 ,将 CPU 复位并从指令 RAM 中 BOOT
### 使用 VGA 屏幕
没有连接屏幕的可以跳过这一步。
如果开发板通过 VGA 连接到了屏幕,可以看到屏幕上出现一个红框,里面空空如也。实际上里面隐藏了 86列32行的字符空位。下面用 **UART调试器** 让屏幕上显示字符。
> 提示:如果屏幕中的红框不在正中间,可以使用屏幕的“自动校正”按钮校正一下
在**DEBUG模式**下,发送一条写命令: **"20000 31323334"** ,可以看到第一行出现了 **4321** 。这是因为显存RAM的起始地址是 0x20000使用 UART调试器 正好向其中的前4个字节写入了 0x34、0x33、0x32、0x31也就是**4321**的ASCII码。
![VGA](./images/vga_show.png)
显存 RAM 占 4096 字节分为32个块对应屏幕中的32个行每块128B前 86 字节对应该行中的前 86 个字符的 ASCII 码。后面128-86个字节不会显示在屏幕上。
显存 RAM 与 数据 RAM 行为相同,即可读又可写,但不能保证一个时钟周期一定能读出数据。
### 使用工具USTCRVSoC-tool
玩了好久的 UART调试也该用 CPU 跑跑 benchmark 了。
**./software/asm-code** 中提供几个汇编语言的小程序作为 benchmark如下表。
| 文件名 | 说明 |
| :----- | :----- |
| io-test/uart_print.S | 用户UART循环打印hello, 即**指令ROM**中的程序 |
| io-test/vga_hello.S | 屏幕上显示hello |
| calculation-test/Fibonacci.S | 递归法计算**斐波那契数列**第8个数 |
| calculation-test/Number2Ascii.S | 将数字转化成ASCII字符串类似于C语言中的 **itoa****sprintf %d** |
| calculation-test/QuickSort.S | 在RAM中初始化一段数据并进行**快速排序** |
| basic-test/big_endian_little_endian.S | 测试这个系统是**大端序**还是**小端序**(这里自然是小端序) |
| basic-test/load_store.S | 完成一些内存读写 |
**USTCRVSoC-tool.exe** 是一个能汇编和烧写的小工具,相当于一个 **汇编语言的IDE**,其路径是 **./tools/USTCRVSoC-tool.exe**,界面如下图。
> **USTCRVSoC-tool** 使用C#编写VisualStudio 的工程路径是 ./USTCRVSoC-tool-VS2012
![USTCRVSoCtool](./images/USTCRVSoC-tool-image.png)
现在尝试让SoC运行一个计算快速排序的程序。步骤
1. **打开 USTCRVSoC-tool.exe**
2. **打开**:点击**打开**按钮,浏览到目录 ./software/asm-code/calculation-test/,打开汇编文件 **QuickSort.S**
3. **汇编**:点击**汇编**按钮可以看到下方框里出现了一串16进制数这就是汇编得到的机器码。
4. **烧写**确保FPGA连接到电脑并烧录了SoC的硬件然后选择正确的 COM 端口,点击**烧写**如果下方状态栏里显示“烧写成功”则CPU就已经开始运行该机器码了。
5. **查看内存**:这时,在右侧点击**DUMP内存**可以看到一个有序的数列。QuickSort程序对-9~+9的乱序数组进行了排序每个数重复了两次。默认的**DUMP内存**不能显示完全可以将长度设置为100这样DUMP的字节数量为0x100字节能看到排序的完整结果。
另外,**USTCRVSoC-tool** 也能查看USER模式下的串口数据。请打开 **io-test/uart_print.S**,汇编并烧写,可以看到右侧的**串口查看**框中不断的打印hello。
现在,你可以尝试运行这些汇编 benchmark或者自己编写汇编进行测试。**Have fun!**
> 关于**普林斯顿结构**:我们虽然区分了**指令RAM**、**数据RAM**、**显存RAM**,但这写存储器在普林斯顿结构中都没有区别。你可以把指令烧写到**数据RAM**、**显存RAM**中去运行,也可以把变量放在**指令RAM**中。甚至,指令和数据都可以放在**数据RAM**中只要地址别冲突程序也能正常运行。但是这样的运行效率就会降低因为CPU的**指令接口**和**数据接口**会**争抢总线**。
# CPU仿真
为了验证 CPU 能够正确地运行 RV32I 指令集,我们使用 RISC-V 官方的指令集测试,提供针对了 CPU 仿真工程。
### 运行仿真
**Vivado** 打开工程 **hardware/Simulation_RiscvCPU/Vivado_Simulation/Simulation_RiscvCPU.xpr** ,可看见顶层文件为 **tb_core.sv** ,然后按照注释的指示进行仿真即可。
# SoC仿真
该仓库提供了 SoC 的整体仿真。
### 运行仿真
**Vivado** 打开工程 **hardware/Simulation_SoC/Vivado_Simulation/Simulation_SoC.xpr** ,工程已经选择了 **tb_soc.sv** 作为仿真的顶层,可以直接进行**行为仿真**。
仿真时运行的指令流来自**指令ROM**,如果你还没修改过**指令ROM**,则仿真时可以看到 **uart_tx** 信号出现 **uart** 发送的波形,这是它在打印 **hello**
### 修改指令ROM
如果你想仿真某个指令流,需要对**指令ROM**进行修改。
**USTCRVSoC-tool** 除了进行烧写,也可以用编译后的指令流生成**指令ROM**的Verilog代码。当你使用**汇编**按钮产生指令流后,可以点击右侧的"保存指令流(Verilog)"按钮,保存时替换 **./RTL/instr_rom.sv**,再重新进行仿真即可。
![语言](https://img.shields.io/badge/语言-systemverilog_(IEEE1800_2005)-CAD09D.svg) ![仿真](https://img.shields.io/badge/仿真-vivado-FF1010.svg) ![部署](https://img.shields.io/badge/部署-vivado-FF1010.svg) ![部署](https://img.shields.io/badge/部署-quartus-blue.svg)
USTCRVSoC
===========================
一个 SystemVerilog 编写的,以一个 RISC-V CPU 为核心的,普林斯顿结构的 SoC ,可作为 MCU 使用。
* **CPU**5段流水线 RISC-V ,支持 **RV32I** 指令集(除了 CSR 指令)。
* **总线**:具有**握手机制**32-bit地址32-bit数据。
* **总线交叉开关 (bus router)**:可使用参数修改总线主从接口的数量和从接口占用的地址空间,以方便拓展外设。
* **交互式 UART 调试**可使用PC上的 Putty、minicom、超级终端等软件进行在线系统复位**、**上传程序**、**查看内存。
* 完全使用 SystemVerilog 实现不调用IP核便于移植和仿真。
## 目录
* [简介](#简介)
* [部署到FPGA](#部署到FPGA)
* 部署到 Nexys4
* 部署到 Arty7
* 部署到 DE0-Nano
* 部署到其它开发板
* [运行与测试](#运行与测试)
* Hello World
* 使用 UART 调试总线
* 使用 VGA 屏幕
* 使用工具USTCRVSoC-tool
* [CPU仿真](#CPU仿真)
* [SoC仿真](#SoC仿真)
# 简介
**图1**展示了SoC的结构总线仲裁器 **bus_router** 也叫总线交叉开关上挂载了3个**主接口**master port和5个**从接口**slave port。这个总线并不来自于任何现有标准例如 AXI 或 APB而是一种简单的同步握手总线命名为 **naive_bus**
| ![SoC](./figures/SoC.png) |
| :-----------------------: |
| **图1**SoC 结构 |
每个**从接口**都占有一段地址空间。当**主接口**访问总线时,**bus_router**判断该地址属于哪个地址空间,然后将它**路由**到相应的**从接口**。下表展示了5个**从接口**的地址空间。
*表1*SoC 地址空间分配
| 外设名称 | 起始地址 | 结束地址 |
| :-----: | :-----: | :----: |
| Instr ROM指令ROM | 0x00000000 | 0x00007fff |
| Instr RAM指令RAM | 0x00008000 | 0x00008fff |
| Data RAM数据RAM | 0x00010000 | 0x00010fff |
| Video RAM显存RAM | 0x00020000 | 0x00020fff |
| ISP UART's user port | 0x00030000 | 0x00030003 |
## 组成部件
* **多主多从总线仲裁器 (bus_router)**:对应文件 naive_bus_router.sv。为每个从设备划分地址空间将主设备的总线读写请求路由到从设备。当多个主设备同时访问一个从设备时还能根据主设备的优先级进行冲突仲裁。
* **RV32I Core**:对应文件 core_top.sv。包括两个主接口。一个用于取指令一个用于读写数据。
* **UART调试器**:对应文件 isp_uart.sv。将UART调试功能和用户UART结合为一体。包括一个主接口和一个从接口。它接收上位机从UART发来的命令对总线进行读写。它可以用于在线烧写、在线调试。也可以接收CPU的命令去发送数据给用户。
* **指令ROM**:对应文件 instr_rom.sv。CPU默认从这里开始取指令里面的指令流是在硬件代码编译综合时就固定的不能在运行时修改。唯一的修改方法是编辑 **instr_rom.sv** 中的代码然后重新编译综合、烧写FPGA逻辑。因此**instr_rom** 多用于仿真。
* **指令RAM**:对应文件 ram_bus_wrapper.sv。请使用UART调试器在线烧写指令流到这里然后将 Boot 地址指向这里再复位SoC后CPU就从这里开始运行指令流。
* **数据RAM**:对应文件 ram_bus_wrapper.sv。存放运行时的数据。
* **显存RAM**:对应文件 video_ram.sv。在屏幕上显示 86列 * 32行 = 2752 个字符,显存 RAM 的 4096B 被划分为 32 个块,每块对应一行,占 128B前 86 字节对应 86 个列。屏幕上显示的是每个字节作为 ASCII 码所对应的字符。
## CPU特性
* 支持: **RV32I** 中的所有 Load、Store、算术、逻辑、移位、比较、跳转。
* 不支持同步、控制状态CSR、环境调用和断点类指令
所有支持的指令包括:
> LB, LH, LW, LBU, LHU, SB, SH, SW, ADD, ADDI, SUB, LUI, AUIPC, XOR, XORI, OR, ORI, AND, ANDI, SLL, SLLI, SRL, SRLI, SRA, SRAI, SLT, SLTI, SLTU, SLTIU, BEQ, BNE, BLT ,BGE, BLTU, BGEU, JAL, JALR
CPU采用5段流水线如**图2**目前支持的流水线特性包括Forward、Loaduse、总线握手等待。
| ![CPU](./figures/CPU.png) |
| :-----------------------: |
| **图2**CPU 结构 |
# 硬件设计代码
| 目录名 | 说明 |
| ------------ | ------------------------------------------------------------ |
| RTL | 全部的 SystemVerilog 代码,其中 soc_top.sv 是整个 SoC 的顶层 |
| FPGA-Arty7 | 基于 Arty7 开发板的 Vivado 工程 |
| FPGA-Nexys4 | 基于 Nexys4 开发板的 Vivado 工程 |
| FPGA-DE0Nano | 基于 DE0Nano 开发板的 Quartus 工程 |
| SIM-CPU | 仿真:对 CPU 进行的指令集测试(使用 RISC-V 官方测试程序) |
| SIM-SoC | 仿真:对整个 SoC 的仿真 |
请注意,所有工程共用 RTL 目录,因此在一个工程里修改代码也会导致其它工程中的代码发生变化。
# 部署到FPGA
目前,我提供了 Xilinx 的 **Nexys4 开发板****Arty7 开发板** 和 Altera 的 **DE0-Nano 开发板** 的工程。
为了进行部署和测试,你需要准备以下的东西:
* **Windows7 系统** 或更高版本的 PC如果使用 Linux 则很难用上我提供的两个C#编写的工具
* **Nexys4 开发板****Arty7 开发板****DE0-Nano 开发板** 或其它 FPGA 开发板
* 开发板对应的开发环境,例如 Nexys4 和 Arty7 开发板对应 VivadoDE0-Nano 对应 Quartus
* 如果你的开发板没有自带 USB 转 UART 电路(例如 DE0-Nano则需要一个 **USB转UART模块**
* 可选屏幕、VGA线
## 部署到 Nexys4
| ![nexys4-connection](./figures/nexys4-connection.png) |
| :---------------------------------------------------: |
| **图3**Nexys4 的硬件连接方法 |
1. **硬件连接**:如**图3**Nexys4 开发板上有一个 USB 口,既可以用于 FPGA 烧录,也可以用于 UART 通信,我们需要连接该 USB 口到电脑。另外VGA 的连接是可选的,你可以把它连接到屏幕上。
2. **综合、烧写**:请用 Vivado 打开工程 **FPGA-Nexys4/USTCRVSoC-nexys4.xpr** 。综合并烧写。
## 部署到 Arty7
1. **硬件连接**Arty7 开发板上有一个 USB 口,既可以用于 FPGA 烧录,也可以用于 UART 通信,我们需要连接该 USB 口到电脑。
2. **综合、烧写**:请用 Vivado 打开工程 **FPGA-Arty7/USTCRVSoC-Arty7.xpr** 。综合并烧写。
## 部署到 DE0-Nano
| ![DE0-Nano](./figures/DE0-Nano.png) |
| :---------------------------------: |
| **图4**DE0-Nano 的硬件连接方法 |
1、**硬件连接**DE0-Nano开发板上既没有USB转UART也没有VGA接口。因此需要外部模块以及一些动手能力。我们使用DE0-Nano上的两排GPIO作为外接模块的引脚接口含义如**图4**。你需要一个USB转UART的模块将UART的TX和RX引脚连接上去使之能与电脑通信。VGA的连接是可选的需要符合上图中VGA的引脚定义。最后连接的效果如**图5**
2、**综合、烧写**:请用 Quartus 打开 **FPGA-DE0Nano/DE0Nano_USTCRVSoC.qpf**。综合并烧写。
| ![de0nano-connection](./figures/de0nano-connection.png) |
| :-----------------------------------------------------: |
| **图5**DE0-Nano 的硬件连接 |
## 部署到其它开发板
如果你手头的 FPGA 开发板不是上述开发板,则需要手动建立工程,连接信号到开发板顶层。分为以下步骤:
1. **建立工程**:建立工程后,需要将 RTL 目录(以及其子目录)中的所有 .sv 文件添加进工程。
2. **编写顶层**SoC 的顶层文件是 **soc_top.sv**,你需要编写一个针对该开发板的顶层文件,调用 **soc_top**,并将 FPGA 的引脚连接到 **soc_top** 中。以下是对 **soc_top** 的信号说明。
3. **综合、烧写到FPGA**
```Verilog
module soc_top #(
// UART接收分频系数请根据clk的时钟频率决定计算公式 UART_RX_CLK_DIV=clk频率(Hz)/460800四舍五入
parameter UART_RX_CLK_DIV = 108,
// UART发送分频系数请根据clk的时钟频率决定计算公式 UART_TX_CLK_DIV=clk频率(Hz)/115200四舍五入
parameter UART_TX_CLK_DIV = 434,
// VGA分频系数请根据clk的时钟频率决定计算公式 VGA_CLK_DIV=clk频率(Hz)/50000000
parameter VGA_CLK_DIV = 1
)(
input logic clk, // SoC 时钟,推荐使用 50MHz 的倍数
input logic isp_uart_rx, // 连接到开发板的 UART RX 引脚
output logic isp_uart_tx, // 连接到开发板的 UART TX 引脚
output logic vga_hsync, vga_vsync, // 连接到VGA可以不连接
output logic vga_red, vga_green, vga_blue // 连接到VGA可以不连接
);
```
# 运行与测试
硬件烧写后,开始对它进行测试。
### Hello World
硬件烧写后,就已经能看到 UART_TX 对应的指示灯在闪烁每闪烁一下其实是在通过UART发送一个"Hello"这说明CPU在运行指令ROM里默认的程序。下面我们来查看这个 Hello。
首先我们需要一款**串口终端软件**,例如:
* minicom
* 串口助手
* 超级终端HyperTerminal
* Putty
这些工具用起来都不够爽快,因此这里使用该仓库中自带的小工具 **UartSession** 做示范。它的路径是 **./UartSession/UartSession.exe **,直接双击打开。
首先,我们双击运行 **UartSession.exe**,可以看到该软件将电脑的所有可用端口都列了出来,并给出了几个选项:
- **打开端口**:输入数字,按回车可以打开数字对应的端口。
- **修改波特率**:输入"baud [数字]"再按回车可以修改波特率。例如输入baud 9600可以修改波特率为9600。
- **刷新端口列表**:输入"refresh",再按回车可以刷新端口列表。
- **退出**:输入"exit"可以退出
波特率默认是115200与我们的 SoC 一致,不需要修改。我们直接从端口列表里找到 FPGA 开发板所对应的COM端口打开它。我们就可以看到窗口中不断显示"hello"根本停不下来如图这说明CPU在正常运行程序。
| ![UartSession2](./figures/UartSession2.png) |
| :------------------------------------------------: |
| **图6**打开COM端口后可以看到不断地打印出 hello |
> 提示:如果不知道端口列表中哪个端口对应 FPGA 开发板,可以拔下开发板的 USB刷新一次端口列表则消失的端口就是开发板对应的端口。然后再插上USB如果FPGA内的电路丢失则需要重新烧录FPGA
### 使用 UART 调试总线
现在界面中不断地打印出"hello",我们打一个回车,可以看到它不再打出"hello",并出现了一个"debug",这样就成功进入了 **DEBUG模式**,如**图7**。
| ![UartSession1](./figures/UartSession1.png) |
| :-----------------------------------------: |
| **图7**:进入调试模式 |
SoC 内的 UART 调试器isp_uart.sv有两种模式
* **USER 模式**:该模式下可以收到 CPU 通过 isp_uart 发送的用户打印数据。FPGA烧写后默认处于这个模式。hello只有在这个模式下才能被我们看到。通过向 uart **发送一个\n** 可以跳出 **USER模式**进入DEBUG模式。
* **DEBUG 模式**:该模式下 CPU 打印的任何数据都会被抑制UART 不再主动发送数据,变成了**一问一答**的形式,用户发送的调试命令和接收到的应答都**以\n结尾**,通过发送"o"可以回到 **USER模式**
下面让我们尝试在 **DEBUG 模式**下对总线进行读写。如**图8**,输入 **"0"** 并按回车会看到对方发来一个8位16进制数。该数就是SoC总线的地址 0x00000000 处读取出的数据。从表1可以看出它是**指令ROM**中的第一条指令。
| ![UartSession3](./figures/UartSession3.png) |
| :-----------------------------------------: |
| **图8**:进入调试模式 |
除了读,我们也可以在总线上进行写操作。我们输入一条写命令 "10000 abcd1234" 并按回车,会看到对方发来 "wr done" ,意为写成功,该命令意为向地址 0x10000 中写入 0xabcd1234从表1可以看出0x10000是数据RAM的首地址
为了验证写成功,输入读命令 "10000" 并按回车,会看到对方发来 "abcd1234" 。
> 注UART 调试器每次读写总线只能以**4字节对齐**的形式并且一次必须读写4字节。
下表显示了 **DEBUG模式** 的所有命令格式。
| 命令类型 | 命令示例 | 返回示例 | 含义 |
| ----- | :----- | :---- | :----- |
| 读总线 | 00020000 | abcd1234 | 地址0x00020000读出的数据是0xabcd1234 |
| 写总线 | 00020004 1276acd0 | wr done | 向地址0x00020004写数据0x1276acd0 |
| 切至USER模式 | o | user | 切换回USER模式|
| 复位 | r00008000 | rst done | CPU 复位并从地址 0x00008000 处开始执行,同时切换回 USER 模式 |
| 非法命令 | ^^$aslfdi | invalid | 发送的命令未定义 |
> 注:无论是发送还是接收,所有命令都以\n或\r或\r\n结尾**UartSession.exe**是自动插入\n的。如果使用串口助手等其它软件需要注意这个问题。
根据这些命令,不难猜出,在线上传程序的流程是:
1. 使用写命令,将指令一条条地写入指令 RAM ,(指令 RAM 的地址空间是 00008000~00008fff
2. 使用复位命令 r00008000 ,将 CPU 复位并从指令 RAM 中启动
### 使用 VGA 屏幕
没有连接屏幕的可以跳过这一步。
如果开发板通过 VGA 连接到了屏幕,可以看到屏幕上出现一个红框,里面空空如也。实际上里面隐藏了 86列32行的字符空位。下面用 **UART调试器** 让屏幕上显示字符。
> 提示:如果屏幕中的红框不在正中间,可以使用屏幕的“自动校正”按钮校正一下
在**DEBUG模式**下,发送一条写命令: **"20000 31323334"** ,可以看到第一行出现了 **4321** 。这是因为显存RAM的起始地址是 0x20000使用 UART调试器 正好向其中的前4个字节写入了 0x34、0x33、0x32、0x31也就是**4321**的ASCII码。
显存 RAM 占 4096 字节分为32个块对应屏幕中的32个行每块128B前 86 字节对应该行中的前 86 个字符的 ASCII 码。后面128-86个字节不会显示在屏幕上。
显存 RAM 与 数据 RAM 行为相同,即可读又可写,但不能保证一个时钟周期一定能读出数据。
| ![VGA](./figures/vga_show.png) |
| :------------------------------------------------------: |
| **图9**用UART调试器向VGA显存中写入数据显示在屏幕上。 |
### 使用工具USTCRVSoC-tool
玩了好久的 UART 调试,也该进入正题了——用 CPU 跑 benchmark 。
**./asm-code** 目录中提供几个汇编语言的小程序作为 benchmark如下表。
| 文件名 | 说明 |
| :----- | :----- |
| io-test/uart_print.S | 用户UART循环打印hello, 即**指令ROM**中的程序 |
| io-test/vga_hello.S | 屏幕上显示hello |
| calculation-test/Fibonacci.S | 递归法计算**斐波那契数列**第8个数 |
| calculation-test/Number2Ascii.S | 将数字转化成ASCII字符串类似于C语言中的 **itoa****sprintf %d** |
| calculation-test/QuickSort.S | 在RAM中初始化一段数据并进行**快速排序** |
| basic-test/big_endian_little_endian.S | 测试这个系统是**大端序**还是**小端序**(这里自然是小端序) |
| basic-test/load_store.S | 完成一些内存读写 |
我们不可能一条一条地把编译得到的机器码手动写入指令RAM这太麻烦了。为此我提供了一个能进行汇编和在线写入指令流的工具**USTCRVSoC-tool.exe** 它相当于一个汇编语言的IDE路径是 **./USTCRVSoC-tool/USTCRVSoC-tool.exe**,双击它打开。
| ![USTCRVSoCtool](./figures/USTCRVSoC.png) |
| :---------------------------------------: |
| **图10**USTCRVSoC-tool 的界面 |
现在我们尝试让SoC运行一个计算快速排序的程序。步骤
1. **打开 USTCRVSoC-tool.exe**
2. **打开**:点击**打开**按钮,浏览到目录 ./asm-code/calculation-test/,打开汇编文件 **QuickSort.S**
3. **汇编**:点击**汇编**按钮可以看到下方框里出现了一串16进制数这就是汇编得到的机器码。
4. **烧写**确保FPGA连接到电脑并烧录了SoC的硬件然后选择正确的 COM 端口,点击**烧写**如果下方状态栏里显示“烧写成功”则CPU就已经开始运行该机器码了。
5. **查看内存**:这时,在右侧点击**DUMP内存**可以看到一个有序的数列。QuickSort程序对-9~+9的乱序数组进行了排序每个数重复了两次。默认的**DUMP内存**不能显示完全可以将长度设置为100这样DUMP的字节数量为0x100字节能看到排序的完整结果。
另外,**USTCRVSoC-tool** 也能查看USER模式下的串口数据。请打开 **io-test/uart_print.S**,汇编并烧写,可以看到右侧的**串口查看**框中不断的打印hello。
现在,你可以尝试运行这些汇编 benchmark或者自己编写汇编进行测试。**Have fun!**
> 关于**普林斯顿结构**:我们虽然区分了**指令RAM**、**数据RAM**、**显存RAM**,但这写存储器在普林斯顿结构中都没有区别。你可以把指令烧写到**数据RAM**、**显存RAM**中去运行,也可以把变量放在**指令RAM**中。甚至,指令和数据都可以放在**数据RAM**中只要地址别冲突程序也能正常运行。但是这样的运行效率就会降低因为CPU的**指令接口**和**数据接口**会**争抢总线**。
# CPU仿真
为了验证 CPU 是否能正确地支持 RV32I 指令集,我进行了 Verilog 仿真在该仿真中CPU 会运行 RISC-V 官方指令集测试程序。
该仿真的相关文件都在 SIM-CPU 目录中,其中的各文件说明如下:
| 文件/目录名 | 说明 |
| ----------- | ------------------------------------------------------------ |
| tb_cpu.sv | testbench代码 |
| vivado_sim | Vivado 工程,调用 tb_cpu.sv 和 RTL 目录里的设计代码进行仿真。 |
| rv32i_test | 包含三个测试程序的汇编代码和指令流 |
要运行 CPU 仿真,请用 Vivado 打开工程 **SIM-CPU/vivado_sim/sim_cpu.xpr** ,可看见顶层文件为 **tb_cpu.sv** ,然后你可以修改参数 `INSTRUCTION_STREAM_FILE` 来指定让 CPU 运行哪个指令流注意应该改成你的PC中的绝对路径。这里我们应该运行 rv32i_test 目录里提供的三个测试程序:
- a_instr_stream.txt :算术逻辑指令相关的测试。
- b_instr_stream.txt Load/Store 指令相关的测试。
- c_instr_stream.txt :跳转指令相关的测试。
然后我们就可以在 Vivado 中运行行为仿真Behavior Simulation这三个测试程序在仿真时大概需要运行 500us 就能结束,测试成功的标志是 gp 寄存器3号寄存器对应 core_regfile.sv 中的 regfile[3] 这个变量)变成 0x00000001 。
# SoC仿真
我还提供了 SoC 的整体仿真。
请用 Vivado 打开工程 **SIM-SoC/vivado_sim/sim_soc.xpr** ,可看见顶层文件为 **tb_soc.sv** ,可以直接进行行为仿真。
仿真时运行的指令流来自**指令ROM**,如果你还没修改过**指令ROM**,则仿真时可以看到 **uart_tx** 信号出现 **uart** 发送的波形,这是它在打印 **hello**
如果你想在仿真时让 CPU 运行其它的指令流,需要对**指令ROM**进行修改。**USTCRVSoC-tool** 除了进行烧写,也可以用编译后的指令流生成**指令ROM**的Verilog代码。当你使用**汇编**按钮产生指令流后,可以点击右侧的"保存指令流(Verilog)"按钮,保存时替换掉 **./RTL/instr_rom.sv**,再重新进行仿真即可。

View File

@ -1,10 +1,12 @@
module core_alu(
input logic [ 6:0] i_opcode, i_funct7,
input logic [ 2:0] i_funct3,
input logic [31:0] i_num1u, i_num2u, i_pc, i_immu,
output logic o_branch_jalr,
output logic o_branch_jalr,
output logic [31:0] o_res, o_branch_jalr_target
);
logic [ 4:0] shamt_rs, shamt_imm;
logic [31:0] num1_plus_imm, pc_plus_imm;
logic signed [31:0] i_num1s, i_num2s, i_imms;

View File

@ -1,7 +1,8 @@
module core_bus_wrapper(
input logic clk, rst_n,
input logic i_re, i_we,
output logic o_conflict,
input logic clk, rstn,
input logic i_re, i_we,
output logic o_conflict,
input logic [ 2:0] i_funct3,
input logic [31:0] i_addr,
input logic [31:0] i_wdata,
@ -49,10 +50,10 @@ always_comb
always_comb
case(i_funct3)
3'b000 : if (addr_lsb==2'b00) wdata <= {24'b0, i_wdata[7:0]};
else if(addr_lsb==2'b01) wdata <= {16'b0, i_wdata[7:0], 8'b0};
else if(addr_lsb==2'b10) wdata <= {8'b0, i_wdata[7:0], 16'b0};
else wdata <= {i_wdata[7:0], 24'b0};
3'b000 : if (addr_lsb==2'b00) wdata <= {24'b0, i_wdata[7:0] };
else if(addr_lsb==2'b01) wdata <= {16'b0, i_wdata[7:0], 8'b0};
else if(addr_lsb==2'b10) wdata <= { 8'b0, i_wdata[7:0], 16'b0};
else wdata <= { i_wdata[7:0], 24'b0};
3'b001 : if (addr_lsb==2'b00) wdata <= {16'b0, i_wdata[15:0]};
else if(addr_lsb==2'b10) wdata <= {i_wdata[15:0], 16'b0};
else wdata <= 0;
@ -62,8 +63,8 @@ always_comb
endcase
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
always @ (posedge clk or negedge rstn)
if(~rstn) begin
i_re_latch <= 1'b0;
rd_addr_lsb <= 2'b0;
rd_funct3 <= 3'b0;

View File

@ -1,7 +1,8 @@
module core_id_stage(
input logic [31:0] i_instr,
output logic o_src1_reg_en, o_src2_reg_en,
output logic o_jal, o_alures2reg, o_memory2reg, o_mem_write,
output logic o_src1_reg_en, o_src2_reg_en,
output logic o_jal, o_alures2reg, o_memory2reg, o_mem_write,
output logic [ 4:0] o_src1_reg_addr, o_src2_reg_addr, o_dst_reg_addr,
output logic [ 6:0] o_opcode, o_funct7,
output logic [ 2:0] o_funct3,
@ -20,7 +21,7 @@ localparam OPCODE_AUIPC = 7'b0010111, // rd=pc+imm
OPCODE_ALI = 7'b0010011, // arithmetic and logical I-TYPE, rd=alu_res
OPCODE_ALR = 7'b0110011, // arithmetic and logical R-TYPE, rd=alu_res
OPCODE_LOAD = 7'b0000011, // load
OPCODE_STORE = 7'b0100011; // store
OPCODE_STORE = 7'b0100011; // store, rd=loadvalue
// generate control signals
assign o_jal = (o_opcode == OPCODE_JAL );

View File

@ -1,14 +1,15 @@
module core_instr_bus_adapter(
input logic clk, rst_n,
input logic clk, rstn,
input logic [31:0] i_boot_addr,
input logic i_stall, i_bus_disable,
input logic i_ex_jmp, i_id_jmp,
input logic i_stall, i_bus_disable,
input logic i_ex_jmp, i_id_jmp,
input logic [31:0] i_ex_target, i_id_target,
output logic [31:0] o_pc, o_instr,
naive_bus.master bus_master
);
logic [31:0] npc, instr_hold=0;
logic bus_busy=1'b0, stall_n = 1'b0;
@ -33,8 +34,8 @@ always_comb
else
npc <= o_pc + 4;
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
always @ (posedge clk or negedge rstn)
if(~rstn) begin
stall_n <= 1'b0;
bus_busy <= 1'b0;
instr_hold <= 0;
@ -53,7 +54,7 @@ always_comb
o_instr <= bus_master.rd_data;
always @ (posedge clk)
if(~rst_n)
if(~rstn)
o_pc <= {i_boot_addr[31:2],2'b00} - 4;
else
o_pc <= npc;

View File

@ -1,6 +1,6 @@
module core_regfile(
input logic clk, rst_n,
input logic clk, rstn,
input logic rd_latch,
// Read port 1
input logic i_re1,
@ -24,15 +24,16 @@ module core_regfile(
input logic [31:0] i_wdata
);
logic [31:0] reg_rdata1, reg_rdata2;
logic [31:0] reg_rdata1 = 0;
logic [31:0] reg_rdata2 = 0;
logic [31:0] forward_data1, forward_data2;
logic from_fw1, from_fw2;
assign o_rdata1 = from_fw1 ? forward_data1 : reg_rdata1;
assign o_rdata2 = from_fw2 ? forward_data2 : reg_rdata2;
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
always @ (posedge clk or negedge rstn)
if(~rstn) begin
from_fw1 <= 1'b0;
forward_data1 <= 0;
end else begin
@ -57,8 +58,8 @@ always @ (posedge clk or negedge rst_n)
end
end
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
always @ (posedge clk or negedge rstn)
if(~rstn) begin
from_fw2 <= 1'b0;
forward_data2 <= 0;
end else begin
@ -83,15 +84,18 @@ always @ (posedge clk or negedge rst_n)
end
end
dual_read_port_ram_32x32 dual_read_port_ram_32x32_for_regfile( // 32bit*32addr
.clk ( clk ),
.i_we ( i_we ),
.i_waddr ( i_waddr ),
.i_wdata ( i_wdata ),
.i_raddr1 ( i_raddr1 ),
.o_rdata1 ( reg_rdata1 ),
.i_raddr2 ( i_raddr2 ),
.o_rdata2 ( reg_rdata2 )
);
// 32bit * 32 regfile
logic [31:0] regfile [32];
always @ (posedge clk)
reg_rdata1 <= regfile[i_raddr1];
always @ (posedge clk)
reg_rdata2 <= regfile[i_raddr2];
always @ (posedge clk)
if(i_we)
regfile[i_waddr] <= i_wdata;
endmodule

View File

@ -1,216 +1,218 @@
module core_top(
input logic clk, rst_n,
input logic [31:0] i_boot_addr,
naive_bus.master instr_master, data_master
);
// ID stage
logic [31:0] id_instr, id_pc;
logic id_src1_reg_en, id_src2_reg_en;
logic [ 4:0] id_src1_reg_addr, id_src2_reg_addr, id_dst_reg_addr;
logic id_jal, id_alures2reg, id_memory2reg, id_memwrite;
logic [ 6:0] id_opcode, id_funct7;
logic [ 2:0] id_funct3;
logic [31:0] id_imm;
// EX stage
logic ex_branch_jalr, ex_alures2reg=1'b0, ex_memory2reg=1'b0, ex_memwrite=1'b0;
logic [6:0] ex_opcode=7'h0, ex_funct7=7'h0;
logic [2:0] ex_funct3=3'h0;
logic [4:0] ex_dst_reg_addr=5'h0;
logic [31:0] ex_alu_res, ex_src1_reg_data, ex_src2_reg_data, ex_pc=0, ex_imm=0, ex_branch_jalr_target;
// MEM stage
logic [2:0] mem_funct3=3'b0;
logic mem_alures2reg=1'b0, mem_memory2reg=1'b0, mem_memwrite=1'b0;
logic [31:0] mem_alu_res=0, mem_mem_wdata=0, mem_mem_addr=0;
logic [4:0] mem_dst_reg_addr=5'h0;
// WB stage
logic wb_memory2reg=1'b0, wb_regwrite=1'b0;
logic [31:0] wb_alu_res=0, wb_reg_wdata, wb_memout;
logic [4:0] wb_dst_reg_addr=5'h0;
// hazard signal
logic id_read_disable, id_stall, ex_stall, ex_nop, mem_stall, wb_nop;
logic loaduse, mem_data_bus_conflict;
// -------------------------------------------------------------------------------
// hazard - comb logic
// -------------------------------------------------------------------------------
assign id_read_disable = loaduse;
assign id_stall = mem_data_bus_conflict;
assign ex_stall = mem_data_bus_conflict;
assign ex_nop = loaduse;
assign mem_stall = mem_data_bus_conflict;
assign wb_nop = mem_data_bus_conflict;
assign loaduse =
(id_src1_reg_en & ex_memory2reg & (id_src1_reg_addr== ex_dst_reg_addr) ) |
(id_src2_reg_en & ex_memory2reg & (id_src2_reg_addr== ex_dst_reg_addr) ) |
(id_src1_reg_en & mem_memory2reg & (id_src1_reg_addr==mem_dst_reg_addr) ) |
(id_src2_reg_en & mem_memory2reg & (id_src2_reg_addr==mem_dst_reg_addr) ) ;
// -------------------------------------------------------------------------------
// Instruction Bus Adapter - timing logic
// -------------------------------------------------------------------------------
core_instr_bus_adapter core_instr_bus_adapter_i(
.clk ( clk ),
.rst_n ( rst_n ),
.i_boot_addr ( i_boot_addr ),
.i_stall ( id_read_disable | id_stall ),
.i_bus_disable ( id_read_disable ),
.i_ex_jmp ( ex_branch_jalr ),
.i_ex_target ( ex_branch_jalr_target ),
.i_id_jmp ( id_jal ),
.i_id_target ( id_pc + id_imm ),
.o_pc ( id_pc ),
.o_instr ( id_instr ),
.bus_master ( instr_master )
);
// -------------------------------------------------------------------------------
// ID stage - comb logic
// -------------------------------------------------------------------------------
core_id_stage core_id_stage_inst(
.i_instr ( id_instr ),
.o_src1_reg_en ( id_src1_reg_en ),
.o_src2_reg_en ( id_src2_reg_en ),
.o_jal ( id_jal ),
.o_alures2reg ( id_alures2reg ),
.o_memory2reg ( id_memory2reg ),
.o_mem_write ( id_memwrite ),
.o_src1_reg_addr ( id_src1_reg_addr ),
.o_src2_reg_addr ( id_src2_reg_addr ),
.o_dst_reg_addr ( id_dst_reg_addr ),
.o_opcode ( id_opcode ),
.o_funct7 ( id_funct7 ),
.o_funct3 ( id_funct3 ),
.o_imm ( id_imm )
);
// -------------------------------------------------------------------------------
// ID-EX stage seg reg - timing logic
// -------------------------------------------------------------------------------
core_regfile core_regfile_inst( // regfile is a part of ID-EX seg reg
.clk ( clk ),
.rst_n ( rst_n ),
.rd_latch ( ex_stall ),
.i_re1 ( id_src1_reg_en ),
.i_raddr1 ( id_src1_reg_addr ),
.o_rdata1 ( ex_src1_reg_data ),
.i_re2 ( id_src2_reg_en ),
.i_raddr2 ( id_src2_reg_addr ),
.o_rdata2 ( ex_src2_reg_data ),
.i_forward1 ( ex_alures2reg ),
.i_faddr1 ( ex_dst_reg_addr ),
.i_fdata1 ( ex_alu_res ),
.i_forward2 ( mem_alures2reg ),
.i_faddr2 ( mem_dst_reg_addr ),
.i_fdata2 ( mem_alu_res ),
.i_we ( wb_regwrite ),
.i_waddr ( wb_dst_reg_addr ),
.i_wdata ( wb_reg_wdata )
);
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
ex_alures2reg <= 1'b0;
ex_memory2reg <= 1'b0;
ex_memwrite <= 1'b0;
ex_dst_reg_addr <= 5'h0;
ex_opcode <= 7'h0;
ex_funct3 <= 3'h0;
ex_funct7 <= 7'h0;
ex_imm <= 0;
ex_pc <= 0;
end else if(~ex_stall) begin
ex_alures2reg <= ex_nop ? 1'b0 : id_alures2reg;
ex_memory2reg <= ex_nop ? 1'b0 : id_memory2reg;
ex_memwrite <= ex_nop ? 1'b0 : id_memwrite;
ex_dst_reg_addr <= ex_nop ? 5'h0 : id_dst_reg_addr;
ex_opcode <= ex_nop ? 7'h0 : id_opcode;
ex_funct7 <= ex_nop ? 7'h0 : id_funct7;
ex_funct3 <= ex_nop ? 3'h0 : id_funct3;
ex_imm <= ex_nop ? 0 : id_imm;
ex_pc <= ex_nop ? 0 : id_pc;
end
// -------------------------------------------------------------------------------
// EX stage - comb logic
// -------------------------------------------------------------------------------
core_alu core_alu_inst(
.i_opcode ( ex_opcode ),
.i_funct7 ( ex_funct7 ),
.i_funct3 ( ex_funct3 ),
.i_num1u ( ex_src1_reg_data ),
.i_num2u ( ex_src2_reg_data ),
.i_pc ( ex_pc ),
.i_immu ( ex_imm ),
.o_branch_jalr ( ex_branch_jalr ),
.o_branch_jalr_target ( ex_branch_jalr_target ),
.o_res ( ex_alu_res )
);
// -------------------------------------------------------------------------------
// EX-MEM stage - timing logic
// -------------------------------------------------------------------------------
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
mem_memory2reg <= 1'b0;
mem_alures2reg <= 1'b0;
mem_alu_res <= 0;
mem_dst_reg_addr<= 5'h0;
mem_memwrite <= 1'b0;
mem_mem_addr <= 0;
mem_mem_wdata <= 0;
mem_funct3 <= 3'b0;
end else if(~mem_stall) begin
mem_memory2reg <= ex_memory2reg;
mem_alures2reg <= ex_alures2reg;
mem_dst_reg_addr<= ex_dst_reg_addr;
mem_alu_res <= ex_alu_res;
mem_memwrite <= ex_memwrite;
mem_mem_addr <= ex_src1_reg_data + ex_imm;
mem_mem_wdata <= ex_src2_reg_data;
mem_funct3 <= ex_funct3;
end
// -------------------------------------------------------------------------------
// MEM-WB stage - timing logic
// -------------------------------------------------------------------------------
core_bus_wrapper core_bus_wrapper_inst(
.clk ( clk ),
.rst_n ( rst_n ),
.i_re ( mem_memory2reg ),
.i_we ( mem_memwrite ),
.o_conflict ( mem_data_bus_conflict ),
.i_funct3 ( mem_funct3 ),
.i_addr ( mem_mem_addr ),
.i_wdata ( mem_mem_wdata ),
.o_rdata ( wb_memout ),
.bus_master ( data_master )
);
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
wb_regwrite <= 1'b0;
wb_memory2reg <= 1'b0;
wb_dst_reg_addr <= 5'h0;
wb_alu_res <= 0;
end else begin
wb_regwrite <= wb_nop ? 1'b0 : (mem_alures2reg | mem_memory2reg);
wb_memory2reg <= wb_nop ? 1'b0 : mem_memory2reg;
wb_dst_reg_addr <= wb_nop ? 5'h0 : mem_dst_reg_addr;
wb_alu_res <= wb_nop ? 0 : mem_alu_res;
end
// -------------------------------------------------------------------------------
// WB stage - comb logic
// -------------------------------------------------------------------------------
assign wb_reg_wdata = wb_memory2reg ? wb_memout : wb_alu_res;
endmodule
module core_top(
input logic clk, rstn,
input logic [31:0] i_boot_addr,
naive_bus.master instr_master, data_master
);
// ID stage
logic [31:0] id_instr, id_pc;
logic id_src1_reg_en, id_src2_reg_en;
logic [ 4:0] id_src1_reg_addr, id_src2_reg_addr, id_dst_reg_addr;
logic id_jal, id_alures2reg, id_memory2reg, id_memwrite;
logic [ 6:0] id_opcode, id_funct7;
logic [ 2:0] id_funct3;
logic [31:0] id_imm;
// EX stage
logic ex_branch_jalr, ex_alures2reg=1'b0, ex_memory2reg=1'b0, ex_memwrite=1'b0;
logic [6:0] ex_opcode=7'h0, ex_funct7=7'h0;
logic [2:0] ex_funct3=3'h0;
logic [4:0] ex_dst_reg_addr=5'h0;
logic [31:0] ex_alu_res, ex_src1_reg_data, ex_src2_reg_data, ex_pc=0, ex_imm=0, ex_branch_jalr_target;
// MEM stage
logic [2:0] mem_funct3=3'b0;
logic mem_alures2reg=1'b0, mem_memory2reg=1'b0, mem_memwrite=1'b0;
logic [31:0] mem_alu_res=0, mem_mem_wdata=0, mem_mem_addr=0;
logic [4:0] mem_dst_reg_addr=5'h0;
// WB stage
logic wb_memory2reg=1'b0, wb_regwrite=1'b0;
logic [31:0] wb_alu_res=0, wb_reg_wdata, wb_memout;
logic [4:0] wb_dst_reg_addr=5'h0;
// hazard signal
logic id_read_disable, id_stall, ex_stall, ex_nop, mem_stall, wb_nop;
logic loaduse, mem_data_bus_conflict;
// -------------------------------------------------------------------------------
// hazard - comb logic
// -------------------------------------------------------------------------------
assign id_read_disable = loaduse;
assign id_stall = mem_data_bus_conflict;
assign ex_stall = mem_data_bus_conflict;
assign ex_nop = loaduse;
assign mem_stall = mem_data_bus_conflict;
assign wb_nop = mem_data_bus_conflict;
assign loaduse =
(id_src1_reg_en & ex_memory2reg & (id_src1_reg_addr== ex_dst_reg_addr) ) |
(id_src2_reg_en & ex_memory2reg & (id_src2_reg_addr== ex_dst_reg_addr) ) |
(id_src1_reg_en & mem_memory2reg & (id_src1_reg_addr==mem_dst_reg_addr) ) |
(id_src2_reg_en & mem_memory2reg & (id_src2_reg_addr==mem_dst_reg_addr) ) ;
// -------------------------------------------------------------------------------
// Instruction Bus Adapter - timing logic
// -------------------------------------------------------------------------------
core_instr_bus_adapter core_instr_bus_i(
.clk ( clk ),
.rstn ( rstn ),
.i_boot_addr ( i_boot_addr ),
.i_stall ( id_read_disable | id_stall ),
.i_bus_disable ( id_read_disable ),
.i_ex_jmp ( ex_branch_jalr ),
.i_ex_target ( ex_branch_jalr_target ),
.i_id_jmp ( id_jal ),
.i_id_target ( id_pc + id_imm ),
.o_pc ( id_pc ),
.o_instr ( id_instr ),
.bus_master ( instr_master )
);
// -------------------------------------------------------------------------------
// ID stage - comb logic
// -------------------------------------------------------------------------------
core_id_stage core_id_stage_i (
.i_instr ( id_instr ),
.o_src1_reg_en ( id_src1_reg_en ),
.o_src2_reg_en ( id_src2_reg_en ),
.o_jal ( id_jal ),
.o_alures2reg ( id_alures2reg ),
.o_memory2reg ( id_memory2reg ),
.o_mem_write ( id_memwrite ),
.o_src1_reg_addr ( id_src1_reg_addr ),
.o_src2_reg_addr ( id_src2_reg_addr ),
.o_dst_reg_addr ( id_dst_reg_addr ),
.o_opcode ( id_opcode ),
.o_funct7 ( id_funct7 ),
.o_funct3 ( id_funct3 ),
.o_imm ( id_imm )
);
// -------------------------------------------------------------------------------
// ID-EX stage seg reg - timing logic
// -------------------------------------------------------------------------------
core_regfile core_regfile_i ( // regfile is a part of ID-EX seg reg
.clk ( clk ),
.rstn ( rstn ),
.rd_latch ( ex_stall ),
.i_re1 ( id_src1_reg_en ),
.i_raddr1 ( id_src1_reg_addr ),
.o_rdata1 ( ex_src1_reg_data ),
.i_re2 ( id_src2_reg_en ),
.i_raddr2 ( id_src2_reg_addr ),
.o_rdata2 ( ex_src2_reg_data ),
.i_forward1 ( ex_alures2reg ),
.i_faddr1 ( ex_dst_reg_addr ),
.i_fdata1 ( ex_alu_res ),
.i_forward2 ( mem_alures2reg ),
.i_faddr2 ( mem_dst_reg_addr ),
.i_fdata2 ( mem_alu_res ),
.i_we ( wb_regwrite ),
.i_waddr ( wb_dst_reg_addr ),
.i_wdata ( wb_reg_wdata )
);
always @ (posedge clk or negedge rstn)
if(~rstn) begin
ex_alures2reg <= 1'b0;
ex_memory2reg <= 1'b0;
ex_memwrite <= 1'b0;
ex_dst_reg_addr <= 5'h0;
ex_opcode <= 7'h0;
ex_funct3 <= 3'h0;
ex_funct7 <= 7'h0;
ex_imm <= 0;
ex_pc <= 0;
end else if(~ex_stall) begin
ex_alures2reg <= ex_nop ? 1'b0 : id_alures2reg;
ex_memory2reg <= ex_nop ? 1'b0 : id_memory2reg;
ex_memwrite <= ex_nop ? 1'b0 : id_memwrite;
ex_dst_reg_addr <= ex_nop ? 5'h0 : id_dst_reg_addr;
ex_opcode <= ex_nop ? 7'h0 : id_opcode;
ex_funct7 <= ex_nop ? 7'h0 : id_funct7;
ex_funct3 <= ex_nop ? 3'h0 : id_funct3;
ex_imm <= ex_nop ? 0 : id_imm;
ex_pc <= ex_nop ? 0 : id_pc;
end
// -------------------------------------------------------------------------------
// EX stage - comb logic
// -------------------------------------------------------------------------------
core_alu core_alu_i (
.i_opcode ( ex_opcode ),
.i_funct7 ( ex_funct7 ),
.i_funct3 ( ex_funct3 ),
.i_num1u ( ex_src1_reg_data ),
.i_num2u ( ex_src2_reg_data ),
.i_pc ( ex_pc ),
.i_immu ( ex_imm ),
.o_branch_jalr ( ex_branch_jalr ),
.o_branch_jalr_target ( ex_branch_jalr_target ),
.o_res ( ex_alu_res )
);
// -------------------------------------------------------------------------------
// EX-MEM stage - timing logic
// -------------------------------------------------------------------------------
always @ (posedge clk or negedge rstn)
if(~rstn) begin
mem_memory2reg <= 1'b0;
mem_alures2reg <= 1'b0;
mem_alu_res <= 0;
mem_dst_reg_addr<= 5'h0;
mem_memwrite <= 1'b0;
mem_mem_addr <= 0;
mem_mem_wdata <= 0;
mem_funct3 <= 3'b0;
end else if(~mem_stall) begin
mem_memory2reg <= ex_memory2reg;
mem_alures2reg <= ex_alures2reg;
mem_dst_reg_addr<= ex_dst_reg_addr;
mem_alu_res <= ex_alu_res;
mem_memwrite <= ex_memwrite;
mem_mem_addr <= ex_src1_reg_data + ex_imm;
mem_mem_wdata <= ex_src2_reg_data;
mem_funct3 <= ex_funct3;
end
// -------------------------------------------------------------------------------
// MEM-WB stage - timing logic
// -------------------------------------------------------------------------------
core_bus_wrapper core_bus_wrapper_i (
.clk ( clk ),
.rstn ( rstn ),
.i_re ( mem_memory2reg ),
.i_we ( mem_memwrite ),
.o_conflict ( mem_data_bus_conflict ),
.i_funct3 ( mem_funct3 ),
.i_addr ( mem_mem_addr ),
.i_wdata ( mem_mem_wdata ),
.o_rdata ( wb_memout ),
.bus_master ( data_master )
);
always @ (posedge clk or negedge rstn)
if(~rstn) begin
wb_regwrite <= 1'b0;
wb_memory2reg <= 1'b0;
wb_dst_reg_addr <= 5'h0;
wb_alu_res <= 0;
end else begin
wb_regwrite <= wb_nop ? 1'b0 : (mem_alures2reg | mem_memory2reg);
wb_memory2reg <= wb_nop ? 1'b0 : mem_memory2reg;
wb_dst_reg_addr <= wb_nop ? 5'h0 : mem_dst_reg_addr;
wb_alu_res <= wb_nop ? 0 : mem_alu_res;
end
// -------------------------------------------------------------------------------
// WB stage - comb logic
// -------------------------------------------------------------------------------
assign wb_reg_wdata = wb_memory2reg ? wb_memout : wb_alu_res;
endmodule

View File

@ -1,43 +1,41 @@
module instr_rom(
input logic clk, rst_n,
naive_bus.slave bus
);
localparam INSTR_CNT = 30'd18;
wire [0:INSTR_CNT-1] [31:0] instr_rom_cell = {
32'h000062b3, // 0x00000000
32'h000302b7, // 0x00000004
32'h06806313, // 0x00000008
32'h00628023, // 0x0000000c
32'h06506313, // 0x00000010
32'h00628023, // 0x00000014
32'h06c06313, // 0x00000018
32'h00628023, // 0x0000001c
32'h06c06313, // 0x00000020
32'h00628023, // 0x00000024
32'h06f06313, // 0x00000028
32'h00628023, // 0x0000002c
32'h00a06313, // 0x00000030
32'h00628023, // 0x00000034
32'h00c003b7, // 0x00000038
32'hfff38393, // 0x0000003c
32'hfe039ee3, // 0x00000040
32'hfc5ff06f // 0x00000044
};
logic [29:0] cell_rd_addr;
assign bus.rd_gnt = bus.rd_req;
assign bus.wr_gnt = bus.wr_req;
assign cell_rd_addr = bus.rd_addr[31:2];
always @ (posedge clk or negedge rst_n)
if(~rst_n)
bus.rd_data <= 0;
else begin
if(bus.rd_req)
bus.rd_data <= (cell_rd_addr>=INSTR_CNT) ? 0 : instr_rom_cell[cell_rd_addr];
else
bus.rd_data <= 0;
end
endmodule
module instr_rom(
input logic clk,
naive_bus.slave bus
);
localparam INSTR_CNT = 30'd18;
wire [31:0] instr_rom_cell [INSTR_CNT] = '{
32'h000062b3, // 0x00000000
32'h000302b7, // 0x00000004
32'h06806313, // 0x00000008
32'h00628023, // 0x0000000c
32'h06506313, // 0x00000010
32'h00628023, // 0x00000014
32'h06c06313, // 0x00000018
32'h00628023, // 0x0000001c
32'h06c06313, // 0x00000020
32'h00628023, // 0x00000024
32'h06f06313, // 0x00000028
32'h00628023, // 0x0000002c
32'h00a06313, // 0x00000030
32'h00628023, // 0x00000034
32'h00c003b7, // 0x00000038
32'hfff38393, // 0x0000003c
32'hfe039ee3, // 0x00000040
32'hfc5ff06f // 0x00000044
};
logic [29:0] cell_rd_addr;
assign bus.rd_gnt = bus.rd_req;
assign bus.wr_gnt = bus.wr_req;
assign cell_rd_addr = bus.rd_addr[31:2];
always @ (posedge clk)
if(bus.rd_req)
bus.rd_data <= (cell_rd_addr>=INSTR_CNT) ? 0 : instr_rom_cell[cell_rd_addr];
endmodule

View File

@ -1,10 +1,11 @@
module naive_bus_router #(
parameter [7:0] N_MASTER = 2,
parameter [7:0] N_SLAVE = 3,
parameter [7:0] N_SLAVE = 3,
parameter [0:N_SLAVE-1][31:0] SLAVES_MASK = { 32'h0000_3fff , 32'h0000_3fff , 32'h0000_3fff },
parameter [0:N_SLAVE-1][31:0] SLAVES_BASE = { 32'h0000_0000 , 32'h0001_0000 , 32'h0002_0000 }
)(
input logic clk, rst_n,
input logic clk, rstn,
naive_bus.slave masters [N_MASTER-1:0] ,
naive_bus.master slaves [ N_SLAVE-1:0]
);
@ -109,8 +110,8 @@ generate
end
endgenerate
always @ (posedge clk or negedge rst_n)
if(~rst_n)
always @ (posedge clk or negedge rstn)
if(~rstn)
master_rd_slv_index_latch <= {N_MASTER{N_SLAVE}};
else
master_rd_slv_index_latch <= master_rd_slv_index;

View File

@ -1,3 +1,4 @@
module ram( // 1024B
input logic clk,
input logic i_we,
@ -7,13 +8,13 @@ module ram( // 1024B
);
initial o_rdata = 8'h0;
logic [7:0] data_ram_cell [0:1023];
logic [7:0] ram_cell [1024];
always @ (posedge clk)
o_rdata <= data_ram_cell[i_raddr];
o_rdata <= ram_cell[i_raddr];
always @ (posedge clk)
if(i_we)
data_ram_cell[i_waddr] <= i_wdata;
ram_cell[i_waddr] <= i_wdata;
endmodule

View File

@ -1,5 +1,6 @@
module ram_bus_wrapper( // 4kB, valid address: 0x0000_0000 ~ 0x0000_0fff
input logic clk, rst_n,
input logic clk,
naive_bus.slave bus
);
@ -11,7 +12,7 @@ assign cell_wr_addr = bus.wr_addr[11:2];
assign bus.rd_gnt = bus.rd_req;
assign bus.wr_gnt = bus.wr_req;
ram ram_block_inst_0(
ram ram_i0(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[0] ),
.i_waddr ( cell_wr_addr ),
@ -19,7 +20,7 @@ ram ram_block_inst_0(
.i_wdata ( bus.wr_data[ 7: 0] ),
.o_rdata ( bus.rd_data[ 7: 0] )
);
ram ram_block_inst_1(
ram ram_i1(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[1] ),
.i_waddr ( cell_wr_addr ),
@ -27,7 +28,7 @@ ram ram_block_inst_1(
.i_wdata ( bus.wr_data[15: 8] ),
.o_rdata ( bus.rd_data[15: 8] )
);
ram ram_block_inst_2(
ram ram_i2(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[2] ),
.i_waddr ( cell_wr_addr ),
@ -35,7 +36,7 @@ ram ram_block_inst_2(
.i_wdata ( bus.wr_data[23:16] ),
.o_rdata ( bus.rd_data[23:16] )
);
ram ram_block_inst_3(
ram ram_i3(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[3] ),
.i_waddr ( cell_wr_addr ),

View File

@ -1,107 +1,110 @@
module soc_top #(
parameter UART_RX_CLK_DIV = 108, // 50MHz/4/115200Hz=108
parameter UART_TX_CLK_DIV = 434, // 50MHz/1/115200Hz=434
parameter VGA_CLK_DIV = 1
)(
// clock, typically 50MHz, UART_RX_CLK_DIV and UART_TX_CLK_DIV and VGA_CLK_DIV must be modify when clk is not 50MHz
input logic clk,
// debug uart and user uart shared signal
input logic isp_uart_rx,
output logic isp_uart_tx,
// VGA signal
output logic vga_hsync, vga_vsync,
output logic vga_red, vga_green, vga_blue
);
logic rst_n;
logic [31:0] boot_addr;
naive_bus bus_masters[3]();
naive_bus bus_slaves[5]();
// shared debug uart and user uart module
isp_uart #(
.UART_RX_CLK_DIV ( UART_RX_CLK_DIV),
.UART_TX_CLK_DIV ( UART_TX_CLK_DIV)
) isp_uart_inst(
.clk ( clk ),
.i_uart_rx ( isp_uart_rx ),
.o_uart_tx ( isp_uart_tx ),
.o_rst_n ( rst_n ),
.o_boot_addr ( boot_addr ),
.bus ( bus_masters[0] ),
.user_uart_bus ( bus_slaves[4] )
);
// RV32I Core
core_top core_top_inst(
.clk ( clk ),
.rst_n ( rst_n ),
.i_boot_addr ( boot_addr ),
.instr_master ( bus_masters[2] ),
.data_master ( bus_masters[1] )
);
// 指令ROM
instr_rom instr_rom_inst(
.clk ( clk ),
.rst_n ( rst_n ),
.bus ( bus_slaves[0] )
);
// 指令RAM
ram_bus_wrapper instr_ram_inst(
.clk ( clk ),
.rst_n ( rst_n ),
.bus ( bus_slaves[1] )
);
// 数据RAM
ram_bus_wrapper data_ram_inst(
.clk ( clk ),
.rst_n ( rst_n ),
.bus ( bus_slaves[2] )
);
// 显存
video_ram #(
.VGA_CLK_DIV ( VGA_CLK_DIV )
)video_ram_inst(
.clk ( clk ),
.rst_n ( rst_n ),
.bus ( bus_slaves[3] ),
.o_vsync ( vga_vsync ),
.o_hsync ( vga_hsync ),
.o_red ( vga_red ),
.o_green ( vga_green ),
.o_blue ( vga_blue )
);
// 3<><33>?5从<35>?<3F>线仲裁<E4BBB2><E8A381>?
//
// 主(越靠前优先级越高):
// 0. UART Debugger?
// 1. Core Data Master
// 2. Core Instruction Master
//
// 从:
// 1. 指令ROM<4F><4D>? 地址空间 00000000~00000fff
// 2. 指令RAM<41><4D>? 地址空间 00008000~00008fff
// 3. 数据RAM<41><4D>? 地址空间 00010000~00010fff
// 4. 显存RAM<41><4D>? 地址空间 00020000~00020fff
// 5. 用户UART 地址空间 00030000~00030003
naive_bus_router #(
.N_MASTER ( 3 ),
.N_SLAVE ( 5 ),
.SLAVES_MASK ( { 32'h0000_0003 , 32'h0000_0fff , 32'h0000_0fff , 32'h0000_0fff , 32'h0000_0fff } ),
.SLAVES_BASE ( { 32'h0003_0000 , 32'h0002_0000 , 32'h0001_0000 , 32'h0000_8000 , 32'h0000_0000 } )
) soc_bus_router_inst (
.clk ( clk ),
.rst_n ( rst_n ),
.masters ( bus_masters ),
.slaves ( bus_slaves )
);
endmodule
module soc_top #(
parameter UART_RX_CLK_DIV = 108, // 50MHz/4/115200Hz=108
parameter UART_TX_CLK_DIV = 434, // 50MHz/1/115200Hz=434
parameter VGA_CLK_DIV = 1
)(
// clock, typically 50MHz, UART_RX_CLK_DIV and UART_TX_CLK_DIV and VGA_CLK_DIV must be modify when clk is not 50MHz
input logic clk,
// debug uart and user uart shared signal
input logic isp_uart_rx,
output logic isp_uart_tx,
// VGA signal
output logic vga_hsync, vga_vsync,
output logic vga_red, vga_green, vga_blue
);
logic rstn;
logic [31:0] boot_addr;
naive_bus bus_masters[3]();
naive_bus bus_slaves[5]();
// shared debug uart and user uart module
isp_uart #(
.UART_RX_CLK_DIV ( UART_RX_CLK_DIV),
.UART_TX_CLK_DIV ( UART_TX_CLK_DIV)
) isp_uart_i(
.clk ( clk ),
.i_uart_rx ( isp_uart_rx ),
.o_uart_tx ( isp_uart_tx ),
.o_rstn ( rstn ),
.o_boot_addr ( boot_addr ),
.bus ( bus_masters[0] ),
.user_uart_bus ( bus_slaves[4] )
);
// RV32I Core
core_top core_top_i(
.clk ( clk ),
.rstn ( rstn ),
.i_boot_addr ( boot_addr ),
.instr_master ( bus_masters[2] ),
.data_master ( bus_masters[1] )
);
// Instruction ROM
instr_rom instr_rom_i(
.clk ( clk ),
.bus ( bus_slaves[0] )
);
// Instruction RAM
ram_bus_wrapper instr_ram_i(
.clk ( clk ),
.bus ( bus_slaves[1] )
);
// Data RAM
ram_bus_wrapper data_ram_i(
.clk ( clk ),
.bus ( bus_slaves[2] )
);
// Video RAM (include VGA controller)
video_ram #(
.VGA_CLK_DIV ( VGA_CLK_DIV )
) video_ram_i (
.clk ( clk ),
.rstn ( rstn ),
.bus ( bus_slaves[3] ),
.o_vsync ( vga_vsync ),
.o_hsync ( vga_hsync ),
.o_red ( vga_red ),
.o_green ( vga_green ),
.o_blue ( vga_blue )
);
// bus router (bus interconnect)
//
// Bus Masters (sort by priority):
// 0. UART Debugger (isp_uart)
// 1. Core Data Master
// 2. Core Instruction Master
//
// Bus Slaves:
// 1. Instruction ROM address: 0x00000000~0x00000fff
// 2. Instruction RAM address: 0x00008000~0x00008fff
// 3. Data RAM address: 0x00010000~0x00010fff
// 4. Video RAM address: 0x00020000~0x00020fff
// 5. user tx uart address: 0x00030000~0x00030003
naive_bus_router #(
.N_MASTER ( 3 ),
.N_SLAVE ( 5 ),
.SLAVES_MASK ( { 32'h0000_0003 , 32'h0000_0fff , 32'h0000_0fff , 32'h0000_0fff , 32'h0000_0fff } ),
.SLAVES_BASE ( { 32'h0003_0000 , 32'h0002_0000 , 32'h0001_0000 , 32'h0000_8000 , 32'h0000_0000 } )
) soc_bus_router_i (
.clk ( clk ),
.rstn ( rstn ),
.masters ( bus_masters ),
.slaves ( bus_slaves )
);
endmodule

View File

@ -1,4 +1,3 @@
// UART
module isp_uart #(
parameter UART_RX_CLK_DIV = 108, // 50MHz/4/115200Hz=108
@ -7,83 +6,78 @@ module isp_uart #(
input logic clk,
input logic i_uart_rx,
output logic o_uart_tx,
output logic o_rst_n,
output logic o_rstn,
output logic [31:0] o_boot_addr,
naive_bus.master bus,
naive_bus.slave user_uart_bus
);
logic isp_uart_tx, user_uart_tx, isp_user_sel=1'b0;
logic uart_tx_line_fin;
logic [ 3:0] rst_chain = 4'b0;
logic rx_ready, rd_ok=1'b0, wr_ok=1'b0, tx_start=1'b0;
logic [ 7:0] rx_data, rx_data_raw, rx_binary;
logic [ 3:0] rx_binary_l;
logic [ 3:0] rstn_shift = 4'b0;
logic uart_tx_line_fin, rx_ready, rd_ok=1'b0, wr_ok=1'b0, tx_start=1'b0;
logic [ 7:0] rx_data;
logic [31:0] addr=0, wr_data=0;
logic [ 7:0][ 7:0] rd_data_ascii;
logic [ 7:0][ 7:0] tx_data = 64'h0;
enum {NEW, CMD,OPEN,CLOSE,ADDR, EQUAL, DATA, FINAL, TRASH} fsm = NEW;
enum {NONE, SELOPEN, SELCLOSE, RST} send_type = NONE;
`define C (rx_data=="r")
`define OP (rx_data=="o")
`define CL (rx_data=="s")
`define C (rx_data=="r") || (rx_data=="R")
`define OP (rx_data=="o") || (rx_data=="O")
`define CL (rx_data=="s") || (rx_data=="S")
`define S (rx_data==" " || rx_data=="\t" )
`define E (rx_data=="\n" || rx_data=="\r" )
`define N ( (rx_data>="0" && rx_data<="9" ) || (rx_data>="a" && rx_data<="f" ) )
`define N ( (rx_data>="0" && rx_data<="9" ) || (rx_data>="a" && rx_data<="f" ) || (rx_data>="A" && rx_data<="F" ) )
function automatic logic [3:0] ascii2hex(input [7:0] ch);
logic [7:0] rxbinary;
if(ch>="0" && ch<="9" ) begin
rxbinary = ch - "0";
end else if(ch>="a" && ch<="f" ) begin
rxbinary = ch - "a" + 8'd10;
end else if(ch>="A" && ch<="F" ) begin
rxbinary = ch - "A" + 8'd10;
end else begin
rxbinary = 8'h0;
end
return rxbinary[3:0];
endfunction
initial o_boot_addr = 0;
assign o_rst_n = &rst_chain;
assign o_rstn = rstn_shift[3];
assign o_uart_tx = isp_user_sel ? isp_uart_tx : user_uart_tx;
initial begin bus.rd_req = 1'b0; bus.wr_req = 1'b0; bus.rd_addr = 0; bus.wr_addr = 0; bus.wr_data = 0; end
assign bus.rd_be = 4'hf;
assign bus.wr_be = 4'hf;
assign rx_binary_l = rx_binary[3:0];
uart_rx #(
.UART_RX_CLK_DIV (UART_RX_CLK_DIV)
) uart_rx_inst (
.clk ( clk ),
.i_rx ( i_uart_rx ),
.o_ready ( rx_ready ),
.o_data ( rx_data_raw )
.UART_RX_CLK_DIV ( UART_RX_CLK_DIV )
) uart_rx_i (
.clk ( clk ),
.i_rx ( i_uart_rx ),
.o_ready ( rx_ready ),
.o_data ( rx_data )
);
uart_tx_line #(
.UART_TX_CLK_DIV (UART_TX_CLK_DIV)
) uart_tx_line_inst (
.clk ( clk ),
.o_tx ( isp_uart_tx ),
.i_start ( tx_start ),
.o_fin ( uart_tx_line_fin ),
.i_data ( tx_data )
.UART_TX_CLK_DIV ( UART_TX_CLK_DIV )
) uart_tx_line_i (
.clk ( clk ),
.o_tx ( isp_uart_tx ),
.i_start ( tx_start ),
.o_fin ( uart_tx_line_fin ),
.i_data ( tx_data )
);
user_uart_tx #(
.UART_TX_CLK_DIV (UART_TX_CLK_DIV)
) user_uart_in_isp_inst (
.clk ( clk ),
.rst_n ( o_rst_n ),
.o_uart_tx ( user_uart_tx ),
.bus ( user_uart_bus )
.UART_TX_CLK_DIV ( UART_TX_CLK_DIV )
) user_uart_in_isp_i (
.clk ( clk ),
.rstn ( o_rstn ),
.o_uart_tx ( user_uart_tx ),
.bus ( user_uart_bus )
);
always_comb // to lower case
if(rx_data_raw>="A" && rx_data_raw<="Z")
rx_data <= rx_data_raw | 8'b00100000;
else
rx_data <= rx_data_raw;
always_comb
if(rx_data>="0" && rx_data<="9" ) begin
rx_binary = rx_data - "0";
end else if(rx_data>="a" && rx_data<="f" ) begin
rx_binary = rx_data - "a" + 8'd10;
end else begin
rx_binary = 8'h0;
end
generate
genvar i;
for(i=0; i<8; i++) begin : convert_binary_to_ascii
@ -136,15 +130,15 @@ always @ (posedge clk)
always @ (posedge clk)
if(uart_tx_line_fin && send_type == RST)
rst_chain <= 4'h0;
rstn_shift <= 4'h0;
else
rst_chain <= {rst_chain[2:0],1'b1};
rstn_shift <= {rstn_shift[2:0],1'b1};
always @ (posedge clk)
if(uart_tx_line_fin && (send_type == RST || send_type == SELOPEN) )
isp_user_sel <= 1'b0; // 切换到USER模式
isp_user_sel <= 1'b0; // user mode
else if(rx_ready && `E )
isp_user_sel <= 1'b1; // 切换到DEBUG模式
isp_user_sel <= 1'b1; // debug mode
always @ (posedge clk)
if (bus.rd_req) begin
@ -166,7 +160,7 @@ always @ (posedge clk)
wr_data <= 0;
end else if(`N) begin
fsm <= ADDR;
addr <= {addr[27:0], rx_binary_l}; // get a addr
addr <= {addr[27:0], ascii2hex(rx_data) }; // get a addr
end else begin
fsm <= TRASH;
end
@ -178,15 +172,15 @@ always @ (posedge clk)
fsm <= TRASH;
end
CMD : if (`E) begin
o_boot_addr <= {wr_data[31:2],2'b00}; // 设置复位的boot地址后两位截断(双字对齐)
o_boot_addr <= {wr_data[31:2],2'b00};
fsm <= NEW; // cmd ok!
addr <= 0;
wr_data <= 0;
end else if(`S) begin
fsm <= CMD;
end else if(`N) begin
fsm <= CMD; // r字符后出现数字说明该复位命令要指定boot地址<E59CB0><E59D80>?
wr_data <= {wr_data[27:0], rx_binary_l}; // get a data
fsm <= CMD;
wr_data <= {wr_data[27:0], ascii2hex(rx_data) }; // get a data
end else begin
fsm <= TRASH;
end
@ -198,7 +192,7 @@ always @ (posedge clk)
wr_data <= 0;
end else if(`N) begin
fsm <= ADDR;
addr <= {addr[27:0], rx_binary_l}; // get a addr
addr <= {addr[27:0], ascii2hex(rx_data) }; // get a addr
end else if(`S) begin
fsm <= EQUAL; // get addr down, waiting for data, maybe a write command
end else begin
@ -212,7 +206,7 @@ always @ (posedge clk)
wr_data <= 0;
end else if(`N) begin
fsm <= DATA; // get a data
wr_data <= {wr_data[27:0], rx_binary_l}; // get a data
wr_data <= {wr_data[27:0], ascii2hex(rx_data) }; // get a data
end else if(`S) begin
fsm <= EQUAL;
end else begin
@ -227,7 +221,7 @@ always @ (posedge clk)
wr_data <= 0;
end else if(`N) begin
fsm <= DATA; // get a data
wr_data <= {wr_data[27:0], rx_binary_l}; // get a data
wr_data <= {wr_data[27:0], ascii2hex(rx_data) }; // get a data
end else if(`S) begin
fsm <= FINAL; // get data down, waiting for \r or \n
end else begin

View File

@ -1,3 +1,4 @@
module uart_rx #(
parameter UART_RX_CLK_DIV = 108 // 50MHz/4/115200Hz=108
)(

View File

@ -2,10 +2,10 @@
module uart_tx_line #(
parameter UART_TX_CLK_DIV = 434 // 50MHz/1/115200Hz=434
)(
input logic clk,
output logic o_tx,
input logic i_start,
output logic o_fin,
input logic clk,
output logic o_tx,
input logic i_start,
output logic o_fin,
input logic [7:0][7:0] i_data
);

View File

@ -2,7 +2,7 @@
module user_uart_tx #(
parameter UART_TX_CLK_DIV = 434 // 50MHz/1/115200Hz=434
)(
input logic clk, rst_n,
input logic clk, rstn,
output logic o_uart_tx,
naive_bus.slave bus
);
@ -14,7 +14,7 @@ logic rd_addr_valid, wr_addr_valid;
logic [31:0] cnt = 0;
logic [ 4:0] tx_cnt = 0;
logic [ 7:0] tx_shift = 8'h0;
logic [ 7:0] fifo_rd_data;
logic [ 7:0] fifo_rd_data = 8'h0;
initial o_uart_tx = 1'b1;
@ -27,8 +27,8 @@ assign fifo_full = (fifo_len==10'h3ff);
assign bus.rd_gnt = bus.rd_req;
always @ (posedge clk or negedge rst_n)
if(~rst_n)
always @ (posedge clk or negedge rstn)
if(~rstn)
bus.rd_data <= 0;
else begin
if(bus.rd_req & rd_addr_valid)
@ -48,8 +48,8 @@ always_comb
bus.wr_gnt <= 1'b0;
end
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
always @ (posedge clk or negedge rstn)
if(~rstn) begin
fifo_wr_pointer <= 10'h0;
end else begin
if(bus.wr_req & wr_addr_valid & bus.wr_be[0] & ~fifo_full) begin
@ -57,14 +57,14 @@ always @ (posedge clk or negedge rst_n)
end
end
always @ (posedge clk or negedge rst_n)
if(~rst_n)
always @ (posedge clk or negedge rstn)
if(~rstn)
cnt <= 0;
else
cnt <= (cnt<UART_TX_CLK_DIV-1) ? cnt+1 : 0;
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
always @ (posedge clk or negedge rstn)
if(~rstn) begin
fifo_rd_pointer <= 10'h0;
o_uart_tx <= 1'b1;
tx_shift <= 8'h00;
@ -85,14 +85,15 @@ always @ (posedge clk or negedge rst_n)
tx_cnt <= fifo_empty ? 5'd0 : TX_CNT;
end
end
logic [7:0] fifo_ram [1024];
ram ram_for_uart_tx_fifo_inst(
.clk ( clk ),
.i_we ( bus.wr_req & wr_addr_valid & bus.wr_be[0] & ~fifo_full ),
.i_waddr ( fifo_wr_pointer ),
.i_wdata ( bus.wr_data[7:0] ),
.i_raddr ( fifo_rd_pointer ),
.o_rdata ( fifo_rd_data )
);
always @ (posedge clk)
fifo_rd_data <= fifo_ram[fifo_rd_pointer];
always @ (posedge clk)
if( bus.wr_req & wr_addr_valid & bus.wr_be[0] & ~fifo_full )
fifo_ram[fifo_wr_pointer] <= bus.wr_data[7:0];
endmodule

154
RTL/vga_char_86x32.sv Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,8 @@
module video_ram #(
parameter VGA_CLK_DIV = 1
)(
input logic clk, rst_n,
input logic clk, rstn,
output logic o_hsync, o_vsync,
output logic o_red, o_green, o_blue,
naive_bus.slave bus
@ -20,13 +21,13 @@ assign bus.rd_data = {vga_rdata[3],vga_rdata[2],vga_rdata[1],vga_rdata[0]};
assign cell_wr_addr = bus.wr_addr[11:2];
assign cell_rd_addr = vga_req ? vga_addr_h : bus.rd_addr[11:2];
always @ (posedge clk or negedge rst_n)
if(~rst_n)
always @ (posedge clk or negedge rstn)
if(~rstn)
vga_addr_l_latch <= 2'b00;
else
vga_addr_l_latch <= vga_addr_l;
ram ram_block_inst_0(
ram ram_i0(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[0] ),
.i_waddr ( cell_wr_addr ),
@ -34,7 +35,7 @@ ram ram_block_inst_0(
.i_raddr ( cell_rd_addr ),
.o_rdata ( vga_rdata[0] )
);
ram ram_block_inst_1(
ram ram_i1(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[1] ),
.i_waddr ( cell_wr_addr ),
@ -42,7 +43,7 @@ ram ram_block_inst_1(
.i_raddr ( cell_rd_addr ),
.o_rdata ( vga_rdata[1] )
);
ram ram_block_inst_2(
ram ram_i2(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[2] ),
.i_waddr ( cell_wr_addr ),
@ -50,7 +51,7 @@ ram ram_block_inst_2(
.i_raddr ( cell_rd_addr ),
.o_rdata ( vga_rdata[2] )
);
ram ram_block_inst_3(
ram ram_i3(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[3] ),
.i_waddr ( cell_wr_addr ),
@ -69,9 +70,8 @@ always_comb
vga_char_86x32 #(
.VGA_CLK_DIV ( VGA_CLK_DIV )
) vga_char_86x32_inst(
) vga_char_86x32_i (
.clk ( clk ),
.rst_n ( rst_n ),
.hsync ( o_hsync ),
.vsync ( o_vsync ),
.red ( o_red ),

69
SIM-CPU/tb_cpu.sv Normal file
View File

@ -0,0 +1,69 @@
`timescale 1ps/1ps
module tb_cpu #(
// Specify the instruction&data stream file to be run here
// notice: this is the file path in my PC, please modify it to the path in your PC
parameter INSTRUCTION_STREAM_FILE = "E:/FPGAcommon/USTC-RVSoC/SIM-CPU/rv32i_test/a_instr_stream.txt" // I provide three test instruction streams here, which are split from the official test of RISC-V RV32I
// b_instr_stream.txt"
// c_instr_stream.txt"
)();
logic clk = 1'b1;
logic rstn = 1'b0;
always #10000 clk = ~clk; // 50MHz clock
initial begin repeat(4) @(posedge clk); rstn <= 1'b1; end
naive_bus bus_masters[2]();
naive_bus bus_slaves [1]();
// RV32I Core
core_top core_top_i (
.clk ( clk ),
.rstn ( rstn ),
.i_boot_addr ( 0 ),
.instr_master ( bus_masters[1] ),
.data_master ( bus_masters[0] )
);
naive_bus_router #(
.N_MASTER ( 2 ),
.N_SLAVE ( 1 ),
.SLAVES_MASK ( { 32'h0000_ffff } ),
.SLAVES_BASE ( { 32'h0000_0000 } )
) soc_bus_router_i (
.clk ( clk ),
.rstn ( rstn ),
.masters ( bus_masters ),
.slaves ( bus_slaves )
);
assign bus_slaves[0].rd_gnt = 1'b1;
assign bus_slaves[0].wr_gnt = 1'b1;
//----------------------------------------------------------------------------------------------------------
// this ram stores both instruction and data
//----------------------------------------------------------------------------------------------------------
logic [31:0] ram [4096];
initial $readmemh(INSTRUCTION_STREAM_FILE, ram);
always @ (posedge clk or negedge rstn)
if(~rstn)
bus_slaves[0].rd_data <= 0;
else
bus_slaves[0].rd_data <= ram[bus_slaves[0].rd_addr[14:2]];
always @ (posedge clk) begin
if(bus_slaves[0].wr_be[0])
ram[bus_slaves[0].wr_addr[14:2]][ 7: 0] <= bus_slaves[0].wr_data[ 7: 0];
if(bus_slaves[0].wr_be[1])
ram[bus_slaves[0].wr_addr[14:2]][15: 8] <= bus_slaves[0].wr_data[15: 8];
if(bus_slaves[0].wr_be[2])
ram[bus_slaves[0].wr_addr[14:2]][23:16] <= bus_slaves[0].wr_data[23:16];
if(bus_slaves[0].wr_be[3])
ram[bus_slaves[0].wr_addr[14:2]][31:24] <= bus_slaves[0].wr_data[31:24];
end
endmodule

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Product Version: Vivado v2018.3 (64-bit) -->
<!-- Product Version: Vivado v2019.1 (64-bit) -->
<!-- -->
<!-- Copyright 1986-2018 Xilinx, Inc. All Rights Reserved. -->
<!-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. -->
<Project Version="7" Minor="39" Path="E:/FPGAcommon/USTCRVSoC/hardware/Simulation_RiscvCPU/Vivado_Simulation/Simulation_RiscvCPU.xpr">
<Project Version="7" Minor="40" Path="E:/FPGAcommon/USTC-RVSoC/SIM-CPU/vivado_sim/sim_cpu.xpr">
<DefaultLaunch Dir="$PRUNDIR"/>
<Configuration>
<Option Name="Id" Val="e372d57f71614fa1a85b5802b90dfd55"/>
@ -31,7 +31,7 @@
<Option Name="EnableBDX" Val="FALSE"/>
<Option Name="DSAVendor" Val="xilinx"/>
<Option Name="DSANumComputeUnits" Val="60"/>
<Option Name="WTXSimLaunchSim" Val="31"/>
<Option Name="WTXSimLaunchSim" Val="56"/>
<Option Name="WTModelSimLaunchSim" Val="0"/>
<Option Name="WTQuestaLaunchSim" Val="0"/>
<Option Name="WTIesLaunchSim" Val="0"/>
@ -71,49 +71,43 @@
</Config>
</FileSet>
<FileSet Name="sim_1" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sim_1">
<File Path="$PPRDIR/../../RTL/core_alu.sv">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/../../RTL/cpu/core_alu.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_bus_wrapper.sv">
<File Path="$PPRDIR/../../RTL/cpu/core_bus_wrapper.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_id_stage.sv">
<File Path="$PPRDIR/../../RTL/cpu/core_id_stage.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_instr_bus_adapter.sv">
<File Path="$PPRDIR/../../RTL/cpu/core_instr_bus_adapter.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_regfile.sv">
<File Path="$PPRDIR/../../RTL/cpu/core_regfile.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/dual_read_port_ram_32x32.sv">
<File Path="$PPRDIR/../../RTL/cpu/core_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -134,7 +128,7 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sim_1/new/tb_core.sv">
<File Path="$PPRDIR/../tb_cpu.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -143,7 +137,7 @@
</File>
<Config>
<Option Name="DesignMode" Val="RTL"/>
<Option Name="TopModule" Val="tb_core"/>
<Option Name="TopModule" Val="tb_cpu"/>
<Option Name="TopLib" Val="xil_defaultlib"/>
<Option Name="TopAutoSet" Val="TRUE"/>
<Option Name="TransportPathDelay" Val="0"/>
@ -179,9 +173,7 @@
<Runs Version="1" Minor="10">
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7a35ticsg324-1L" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" IncludeInArchive="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2018">
<Desc>Vivado Synthesis Defaults</Desc>
</StratHandle>
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2018"/>
<Step Id="synth_design"/>
</Strategy>
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2018"/>
@ -189,9 +181,7 @@
</Run>
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a35ticsg324-1L" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" SynthRun="synth_1" IncludeInArchive="true" GenFullBitstream="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2018">
<Desc>Default settings for Implementation.</Desc>
</StratHandle>
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2018"/>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
@ -237,6 +227,28 @@
</Dashboards>
</DashboardSummary>
<BootPmcSettings Version="1" Minor="0">
<Parameters/>
<Parameters>
<Parameter Name="PMC_CDO.ATTRS.LOADADDR" Value="" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_FB_CLK" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_FREQ" Value="300" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_BUS_WIDTH" Value="x1" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_DATA_MODE" Value="Single" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_FREQ" Value="200" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_SLOT_TYPE" Value="SD 2.0" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_DATA_TRANSFER_MODE" Value="4Bit" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_FREQ" Value="200" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_SLOT_TYPE" Value="SD 2.0" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_DATA_TRANSFER_MODE" Value="4Bit" Type="string"/>
<Parameter Name="BOOT.PMC.OSPI_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.OSPI_FREQ" Value="300" Type="string"/>
<Parameter Name="BOOT.USB_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SMAP_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SMAP_DATA_WIDTH" Value="32 Bit" Type="string"/>
<Parameter Name="BOOT.PMC.OSC_FREQ" Value="33.333" Type="string"/>
<Parameter Name="BOOT.SECONDARY.PCIE_ENABLE" Value="0" Type="string"/>
</Parameters>
</BootPmcSettings>
</Project>

12
SIM-SoC/questasim.tcl Normal file
View File

@ -0,0 +1,12 @@
quit -sim
vlog -sv -incr tb_soc.sv ../RTL/*.sv ../RTL/cpu/*.sv ../RTL/uart/*.sv
vsim -t ps -voptargs="+acc" work.tb_soc
log -r /*
radix 16
do wave.do
run 1000us

27
SIM-SoC/tb_soc.sv Normal file
View File

@ -0,0 +1,27 @@
`timescale 1ps/1ps
module tb_soc();
logic clk = 1'b1;
always #10000 clk = ~clk; // 50MHz clock
wire uart_tx;
wire vga_hsync, vga_vsync, vga_red, vga_green, vga_blue;
soc_top #(
.UART_RX_CLK_DIV ( 108 ), // 50MHz/4/115200 = 108
.UART_TX_CLK_DIV ( 434 ), // 50MHz/1/115200 = 434
.VGA_CLK_DIV ( 1 )
) soc_i (
.clk ( clk ),
.isp_uart_rx ( 1'b1 ),
.isp_uart_tx ( uart_tx ),
.vga_hsync ( vga_hsync ),
.vga_vsync ( vga_vsync ),
.vga_red ( vga_red ),
.vga_green ( vga_green ),
.vga_blue ( vga_blue )
);
endmodule

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Product Version: Vivado v2018.3 (64-bit) -->
<!-- Product Version: Vivado v2019.1 (64-bit) -->
<!-- -->
<!-- Copyright 1986-2018 Xilinx, Inc. All Rights Reserved. -->
<!-- Copyright 1986-2019 Xilinx, Inc. All Rights Reserved. -->
<Project Version="7" Minor="39" Path="E:/FPGAcommon/USTCRVSoC/hardware/Simulation_SoC/Vivado_Simulation/Simulation_SoC.xpr">
<Project Version="7" Minor="40" Path="E:/FPGAcommon/USTC-RVSoC/SIM-SoC/vivado_sim/sim_soc.xpr">
<DefaultLaunch Dir="$PRUNDIR"/>
<Configuration>
<Option Name="Id" Val="6bcec6d9390e4db5bc5d5e1d4ecf8359"/>
@ -31,7 +31,7 @@
<Option Name="EnableBDX" Val="FALSE"/>
<Option Name="DSAVendor" Val="xilinx"/>
<Option Name="DSANumComputeUnits" Val="60"/>
<Option Name="WTXSimLaunchSim" Val="3"/>
<Option Name="WTXSimLaunchSim" Val="4"/>
<Option Name="WTModelSimLaunchSim" Val="0"/>
<Option Name="WTQuestaLaunchSim" Val="0"/>
<Option Name="WTIesLaunchSim" Val="0"/>
@ -71,56 +71,43 @@
</Config>
</FileSet>
<FileSet Name="sim_1" Type="SimulationSrcs" RelSrcDir="$PSRCDIR/sim_1">
<File Path="$PPRDIR/../../RTL/char8x16_rom.sv">
<Filter Type="Srcs"/>
<File Path="$PPRDIR/../../RTL/cpu/core_alu.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_alu.sv">
<File Path="$PPRDIR/../../RTL/cpu/core_bus_wrapper.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_bus_wrapper.sv">
<File Path="$PPRDIR/../../RTL/cpu/core_id_stage.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_id_stage.sv">
<File Path="$PPRDIR/../../RTL/cpu/core_instr_bus_adapter.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_instr_bus_adapter.sv">
<File Path="$PPRDIR/../../RTL/cpu/core_regfile.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_regfile.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/core_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/dual_read_port_ram_32x32.sv">
<File Path="$PPRDIR/../../RTL/cpu/core_top.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -134,7 +121,7 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/isp_uart.sv">
<File Path="$PPRDIR/../../RTL/uart/isp_uart.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -162,13 +149,6 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/ram128B.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/ram_bus_wrapper.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
@ -183,21 +163,21 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/uart_rx.sv">
<File Path="$PPRDIR/../../RTL/uart/uart_rx.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/uart_tx_line.sv">
<File Path="$PPRDIR/../../RTL/uart/uart_tx_line.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PPRDIR/../../RTL/user_uart_tx.sv">
<File Path="$PPRDIR/../../RTL/uart/user_uart_tx.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -218,7 +198,7 @@
<Attr Name="UsedIn" Val="simulation"/>
</FileInfo>
</File>
<File Path="$PSRCDIR/sim_1/new/tb_soc.sv">
<File Path="$PPRDIR/../tb_soc.sv">
<FileInfo>
<Attr Name="UsedIn" Val="synthesis"/>
<Attr Name="UsedIn" Val="implementation"/>
@ -263,9 +243,7 @@
<Runs Version="1" Minor="10">
<Run Id="synth_1" Type="Ft3:Synth" SrcSet="sources_1" Part="xc7a35ticsg324-1L" ConstrsSet="constrs_1" Description="Vivado Synthesis Defaults" AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" IncludeInArchive="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2018">
<Desc>Vivado Synthesis Defaults</Desc>
</StratHandle>
<StratHandle Name="Vivado Synthesis Defaults" Flow="Vivado Synthesis 2018"/>
<Step Id="synth_design"/>
</Strategy>
<ReportStrategy Name="Vivado Synthesis Default Reports" Flow="Vivado Synthesis 2018"/>
@ -273,9 +251,7 @@
</Run>
<Run Id="impl_1" Type="Ft2:EntireDesign" Part="xc7a35ticsg324-1L" ConstrsSet="constrs_1" Description="Default settings for Implementation." AutoIncrementalCheckpoint="false" WriteIncrSynthDcp="false" State="current" SynthRun="synth_1" IncludeInArchive="true" GenFullBitstream="true">
<Strategy Version="1" Minor="2">
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2018">
<Desc>Default settings for Implementation.</Desc>
</StratHandle>
<StratHandle Name="Vivado Implementation Defaults" Flow="Vivado Implementation 2018"/>
<Step Id="init_design"/>
<Step Id="opt_design"/>
<Step Id="power_opt_design"/>
@ -321,6 +297,28 @@
</Dashboards>
</DashboardSummary>
<BootPmcSettings Version="1" Minor="0">
<Parameters/>
<Parameters>
<Parameter Name="PMC_CDO.ATTRS.LOADADDR" Value="" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_FB_CLK" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_FREQ" Value="300" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_BUS_WIDTH" Value="x1" Type="string"/>
<Parameter Name="BOOT.PMC.QSPI_DATA_MODE" Value="Single" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_FREQ" Value="200" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_SLOT_TYPE" Value="SD 2.0" Type="string"/>
<Parameter Name="BOOT.PMC.SD0_DATA_TRANSFER_MODE" Value="4Bit" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_FREQ" Value="200" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_SLOT_TYPE" Value="SD 2.0" Type="string"/>
<Parameter Name="BOOT.PMC.SD1_DATA_TRANSFER_MODE" Value="4Bit" Type="string"/>
<Parameter Name="BOOT.PMC.OSPI_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.OSPI_FREQ" Value="300" Type="string"/>
<Parameter Name="BOOT.USB_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SMAP_ENABLE" Value="0" Type="string"/>
<Parameter Name="BOOT.PMC.SMAP_DATA_WIDTH" Value="32 Bit" Type="string"/>
<Parameter Name="BOOT.PMC.OSC_FREQ" Value="33.333" Type="string"/>
<Parameter Name="BOOT.SECONDARY.PCIE_ENABLE" Value="0" Type="string"/>
</Parameters>
</BootPmcSettings>
</Project>

View File

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "USTCRVSoC-tool", "USTCRVSoC-tool\USTCRVSoC-tool.csproj", "{54C41CBE-83B8-44F7-ABCB-85F543A690CC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{54C41CBE-83B8-44F7-ABCB-85F543A690CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{54C41CBE-83B8-44F7-ABCB-85F543A690CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{54C41CBE-83B8-44F7-ABCB-85F543A690CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{54C41CBE-83B8-44F7-ABCB-85F543A690CC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,6 +0,0 @@
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup>
</configuration>

View File

@ -1,701 +0,0 @@
namespace USTCRVSoC_tool
{
partial class MainForm
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.fileSelectionText = new System.Windows.Forms.TextBox();
this.fileSelectionBtn = new System.Windows.Forms.Button();
this.compileGroup = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.otherSaveBtn = new System.Windows.Forms.Button();
this.saveBtn = new System.Windows.Forms.Button();
this.codeText = new System.Windows.Forms.TextBox();
this.compilePromptText = new System.Windows.Forms.TextBox();
this.HexStreamGroup = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.binText = new System.Windows.Forms.TextBox();
this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
this.saveVerilog = new System.Windows.Forms.Button();
this.compileBtn = new System.Windows.Forms.Button();
this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel();
this.programBtn = new System.Windows.Forms.Button();
this.portSelectionBox = new System.Windows.Forms.ComboBox();
this.bootAddrGroup = new System.Windows.Forms.GroupBox();
this.bootAddrTextBox = new System.Windows.Forms.TextBox();
this.MainLayout = new System.Windows.Forms.TableLayoutPanel();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel7 = new System.Windows.Forms.TableLayoutPanel();
this.userPortTextBox = new System.Windows.Forms.TextBox();
this.tableLayoutPanel8 = new System.Windows.Forms.TableLayoutPanel();
this.userPortClearBtn = new System.Windows.Forms.Button();
this.userPortOpenCloseBtn = new System.Windows.Forms.Button();
this.userPortShowHex = new System.Windows.Forms.CheckBox();
this.UserPortRecvCountLabel = new System.Windows.Forms.Label();
this.DumpGroup = new System.Windows.Forms.GroupBox();
this.DumpLayout = new System.Windows.Forms.TableLayoutPanel();
this. = new System.Windows.Forms.TextBox();
this.Layout = new System.Windows.Forms.TableLayoutPanel();
this. = new System.Windows.Forms.TextBox();
this. = new System.Windows.Forms.TextBox();
this.Title = new System.Windows.Forms.Label();
this.Title = new System.Windows.Forms.Label();
this.DUMP内存 = new System.Windows.Forms.Button();
this.serialPort = new System.IO.Ports.SerialPort(this.components);
this.compileGroup.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
this.HexStreamGroup.SuspendLayout();
this.tableLayoutPanel4.SuspendLayout();
this.tableLayoutPanel5.SuspendLayout();
this.tableLayoutPanel6.SuspendLayout();
this.bootAddrGroup.SuspendLayout();
this.MainLayout.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.groupBox1.SuspendLayout();
this.tableLayoutPanel7.SuspendLayout();
this.tableLayoutPanel8.SuspendLayout();
this.DumpGroup.SuspendLayout();
this.DumpLayout.SuspendLayout();
this.Layout.SuspendLayout();
this.SuspendLayout();
//
// fileSelectionText
//
this.fileSelectionText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.fileSelectionText.Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.fileSelectionText.Location = new System.Drawing.Point(5, 5);
this.fileSelectionText.Margin = new System.Windows.Forms.Padding(5);
this.fileSelectionText.Name = "fileSelectionText";
this.fileSelectionText.ReadOnly = true;
this.fileSelectionText.Size = new System.Drawing.Size(187, 28);
this.fileSelectionText.TabIndex = 0;
//
// fileSelectionBtn
//
this.fileSelectionBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.fileSelectionBtn.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.fileSelectionBtn.Location = new System.Drawing.Point(200, 3);
this.fileSelectionBtn.Name = "fileSelectionBtn";
this.fileSelectionBtn.Size = new System.Drawing.Size(114, 34);
this.fileSelectionBtn.TabIndex = 1;
this.fileSelectionBtn.Text = "打开...";
this.fileSelectionBtn.UseVisualStyleBackColor = true;
this.fileSelectionBtn.Click += new System.EventHandler(this.fileSelectionBtn_Click);
//
// compileGroup
//
this.compileGroup.Controls.Add(this.tableLayoutPanel3);
this.compileGroup.Dock = System.Windows.Forms.DockStyle.Fill;
this.compileGroup.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.compileGroup.Location = new System.Drawing.Point(7, 7);
this.compileGroup.Margin = new System.Windows.Forms.Padding(7);
this.compileGroup.Name = "compileGroup";
this.compileGroup.Size = new System.Drawing.Size(563, 64);
this.compileGroup.TabIndex = 2;
this.compileGroup.TabStop = false;
this.compileGroup.Text = "文件";
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 4;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 120F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 120F));
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 120F));
this.tableLayoutPanel3.Controls.Add(this.otherSaveBtn, 3, 0);
this.tableLayoutPanel3.Controls.Add(this.saveBtn, 2, 0);
this.tableLayoutPanel3.Controls.Add(this.fileSelectionBtn, 1, 0);
this.tableLayoutPanel3.Controls.Add(this.fileSelectionText, 0, 0);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 21);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 1;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(557, 40);
this.tableLayoutPanel3.TabIndex = 7;
//
// otherSaveBtn
//
this.otherSaveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.otherSaveBtn.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.otherSaveBtn.Location = new System.Drawing.Point(440, 3);
this.otherSaveBtn.Name = "otherSaveBtn";
this.otherSaveBtn.Size = new System.Drawing.Size(114, 34);
this.otherSaveBtn.TabIndex = 5;
this.otherSaveBtn.Text = "另存...";
this.otherSaveBtn.UseVisualStyleBackColor = true;
this.otherSaveBtn.Click += new System.EventHandler(this.otherSaveBtn_Click);
//
// saveBtn
//
this.saveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.saveBtn.Enabled = false;
this.saveBtn.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.saveBtn.Location = new System.Drawing.Point(320, 3);
this.saveBtn.Name = "saveBtn";
this.saveBtn.Size = new System.Drawing.Size(114, 34);
this.saveBtn.TabIndex = 4;
this.saveBtn.Text = "保存";
this.saveBtn.UseVisualStyleBackColor = true;
this.saveBtn.Click += new System.EventHandler(this.saveBtn_Click);
//
// codeText
//
this.codeText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.codeText.Font = new System.Drawing.Font("Consolas", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.codeText.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
this.codeText.Location = new System.Drawing.Point(3, 81);
this.codeText.Multiline = true;
this.codeText.Name = "codeText";
this.codeText.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.codeText.Size = new System.Drawing.Size(571, 504);
this.codeText.TabIndex = 4;
//
// compilePromptText
//
this.compilePromptText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.compilePromptText.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.compilePromptText.Location = new System.Drawing.Point(3, 591);
this.compilePromptText.Multiline = true;
this.compilePromptText.Name = "compilePromptText";
this.compilePromptText.ReadOnly = true;
this.compilePromptText.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.compilePromptText.Size = new System.Drawing.Size(571, 156);
this.compilePromptText.TabIndex = 3;
//
// HexStreamGroup
//
this.HexStreamGroup.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.HexStreamGroup.Controls.Add(this.tableLayoutPanel4);
this.HexStreamGroup.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.HexStreamGroup.Location = new System.Drawing.Point(586, 3);
this.HexStreamGroup.Name = "HexStreamGroup";
this.HexStreamGroup.Size = new System.Drawing.Size(244, 750);
this.HexStreamGroup.TabIndex = 5;
this.HexStreamGroup.TabStop = false;
this.HexStreamGroup.Text = "指令流";
//
// tableLayoutPanel4
//
this.tableLayoutPanel4.ColumnCount = 1;
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel4.Controls.Add(this.binText, 0, 3);
this.tableLayoutPanel4.Controls.Add(this.tableLayoutPanel5, 0, 0);
this.tableLayoutPanel4.Controls.Add(this.tableLayoutPanel6, 0, 1);
this.tableLayoutPanel4.Controls.Add(this.bootAddrGroup, 0, 2);
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel4.Location = new System.Drawing.Point(3, 21);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
this.tableLayoutPanel4.RowCount = 4;
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F));
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F));
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 60F));
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel4.Size = new System.Drawing.Size(238, 726);
this.tableLayoutPanel4.TabIndex = 0;
//
// binText
//
this.binText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.binText.Font = new System.Drawing.Font("Consolas", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.binText.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(192)))));
this.binText.Location = new System.Drawing.Point(3, 163);
this.binText.Multiline = true;
this.binText.Name = "binText";
this.binText.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.binText.Size = new System.Drawing.Size(232, 560);
this.binText.TabIndex = 5;
//
// tableLayoutPanel5
//
this.tableLayoutPanel5.ColumnCount = 2;
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 30F));
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 70F));
this.tableLayoutPanel5.Controls.Add(this.saveVerilog, 1, 0);
this.tableLayoutPanel5.Controls.Add(this.compileBtn, 0, 0);
this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel5.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
this.tableLayoutPanel5.RowCount = 1;
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel5.Size = new System.Drawing.Size(232, 44);
this.tableLayoutPanel5.TabIndex = 0;
//
// saveVerilog
//
this.saveVerilog.Dock = System.Windows.Forms.DockStyle.Fill;
this.saveVerilog.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.saveVerilog.Location = new System.Drawing.Point(72, 3);
this.saveVerilog.Name = "saveVerilog";
this.saveVerilog.Size = new System.Drawing.Size(157, 38);
this.saveVerilog.TabIndex = 2;
this.saveVerilog.Text = "保存指令流 (Verilog)";
this.saveVerilog.UseVisualStyleBackColor = true;
this.saveVerilog.Click += new System.EventHandler(this.saveVerilog_Click);
//
// compileBtn
//
this.compileBtn.Dock = System.Windows.Forms.DockStyle.Fill;
this.compileBtn.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.compileBtn.Location = new System.Drawing.Point(3, 3);
this.compileBtn.Name = "compileBtn";
this.compileBtn.Size = new System.Drawing.Size(63, 38);
this.compileBtn.TabIndex = 0;
this.compileBtn.Text = "汇编";
this.compileBtn.UseVisualStyleBackColor = true;
this.compileBtn.Click += new System.EventHandler(this.compileBtn_Click);
//
// tableLayoutPanel6
//
this.tableLayoutPanel6.ColumnCount = 2;
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel6.Controls.Add(this.programBtn, 1, 0);
this.tableLayoutPanel6.Controls.Add(this.portSelectionBox, 0, 0);
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel6.Location = new System.Drawing.Point(3, 53);
this.tableLayoutPanel6.Name = "tableLayoutPanel6";
this.tableLayoutPanel6.RowCount = 1;
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel6.Size = new System.Drawing.Size(232, 44);
this.tableLayoutPanel6.TabIndex = 1;
this.tableLayoutPanel6.Paint += new System.Windows.Forms.PaintEventHandler(this.tableLayoutPanel6_Paint);
//
// programBtn
//
this.programBtn.Dock = System.Windows.Forms.DockStyle.Fill;
this.programBtn.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.programBtn.Location = new System.Drawing.Point(157, 3);
this.programBtn.Name = "programBtn";
this.programBtn.Size = new System.Drawing.Size(72, 38);
this.programBtn.TabIndex = 3;
this.programBtn.Text = "烧写";
this.programBtn.UseVisualStyleBackColor = true;
this.programBtn.Click += new System.EventHandler(this.programBtn_Click);
//
// portSelectionBox
//
this.portSelectionBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.portSelectionBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.portSelectionBox.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.portSelectionBox.FormattingEnabled = true;
this.portSelectionBox.Location = new System.Drawing.Point(3, 3);
this.portSelectionBox.Name = "portSelectionBox";
this.portSelectionBox.Size = new System.Drawing.Size(148, 28);
this.portSelectionBox.TabIndex = 0;
this.portSelectionBox.DropDown += new System.EventHandler(this.InitializeCurrentPort);
//
// bootAddrGroup
//
this.bootAddrGroup.Controls.Add(this.bootAddrTextBox);
this.bootAddrGroup.Dock = System.Windows.Forms.DockStyle.Fill;
this.bootAddrGroup.Location = new System.Drawing.Point(3, 103);
this.bootAddrGroup.Name = "bootAddrGroup";
this.bootAddrGroup.Size = new System.Drawing.Size(232, 54);
this.bootAddrGroup.TabIndex = 6;
this.bootAddrGroup.TabStop = false;
this.bootAddrGroup.Text = "BOOT地址";
//
// bootAddrTextBox
//
this.bootAddrTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.bootAddrTextBox.Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.bootAddrTextBox.Location = new System.Drawing.Point(3, 21);
this.bootAddrTextBox.Margin = new System.Windows.Forms.Padding(5);
this.bootAddrTextBox.Name = "bootAddrTextBox";
this.bootAddrTextBox.Size = new System.Drawing.Size(226, 28);
this.bootAddrTextBox.TabIndex = 1;
this.bootAddrTextBox.Text = "00008000";
this.bootAddrTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// MainLayout
//
this.MainLayout.ColumnCount = 4;
this.MainLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.MainLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 250F));
this.MainLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 250F));
this.MainLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 380F));
this.MainLayout.Controls.Add(this.HexStreamGroup, 1, 0);
this.MainLayout.Controls.Add(this.tableLayoutPanel2, 0, 0);
this.MainLayout.Controls.Add(this.groupBox1, 2, 0);
this.MainLayout.Controls.Add(this.DumpGroup, 3, 0);
this.MainLayout.Dock = System.Windows.Forms.DockStyle.Fill;
this.MainLayout.Location = new System.Drawing.Point(0, 0);
this.MainLayout.Name = "MainLayout";
this.MainLayout.RowCount = 1;
this.MainLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.MainLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.MainLayout.Size = new System.Drawing.Size(1463, 756);
this.MainLayout.TabIndex = 6;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 1;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel2.Controls.Add(this.compileGroup, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.codeText, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.compilePromptText, 0, 2);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 3;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 78F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 76F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 24F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(577, 750);
this.tableLayoutPanel2.TabIndex = 6;
//
// groupBox1
//
this.groupBox1.Controls.Add(this.tableLayoutPanel7);
this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox1.Location = new System.Drawing.Point(836, 3);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(244, 750);
this.groupBox1.TabIndex = 7;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "串口查看";
//
// tableLayoutPanel7
//
this.tableLayoutPanel7.ColumnCount = 1;
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel7.Controls.Add(this.userPortTextBox, 0, 1);
this.tableLayoutPanel7.Controls.Add(this.tableLayoutPanel8, 0, 0);
this.tableLayoutPanel7.Controls.Add(this.UserPortRecvCountLabel, 0, 2);
this.tableLayoutPanel7.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel7.Location = new System.Drawing.Point(3, 21);
this.tableLayoutPanel7.Name = "tableLayoutPanel7";
this.tableLayoutPanel7.RowCount = 3;
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 90F));
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
this.tableLayoutPanel7.Size = new System.Drawing.Size(238, 726);
this.tableLayoutPanel7.TabIndex = 0;
//
// userPortTextBox
//
this.userPortTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.userPortTextBox.Font = new System.Drawing.Font("Consolas", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.userPortTextBox.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))));
this.userPortTextBox.Location = new System.Drawing.Point(3, 93);
this.userPortTextBox.Multiline = true;
this.userPortTextBox.Name = "userPortTextBox";
this.userPortTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.userPortTextBox.Size = new System.Drawing.Size(232, 590);
this.userPortTextBox.TabIndex = 6;
//
// tableLayoutPanel8
//
this.tableLayoutPanel8.ColumnCount = 2;
this.tableLayoutPanel8.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel8.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 25F));
this.tableLayoutPanel8.Controls.Add(this.userPortClearBtn, 1, 1);
this.tableLayoutPanel8.Controls.Add(this.userPortOpenCloseBtn, 1, 0);
this.tableLayoutPanel8.Controls.Add(this.userPortShowHex, 0, 1);
this.tableLayoutPanel8.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel8.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel8.Name = "tableLayoutPanel8";
this.tableLayoutPanel8.RowCount = 2;
this.tableLayoutPanel8.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel8.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel8.Size = new System.Drawing.Size(232, 84);
this.tableLayoutPanel8.TabIndex = 2;
//
// userPortClearBtn
//
this.userPortClearBtn.Dock = System.Windows.Forms.DockStyle.Fill;
this.userPortClearBtn.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.userPortClearBtn.Location = new System.Drawing.Point(157, 45);
this.userPortClearBtn.Name = "userPortClearBtn";
this.userPortClearBtn.Size = new System.Drawing.Size(72, 36);
this.userPortClearBtn.TabIndex = 4;
this.userPortClearBtn.Text = "清空";
this.userPortClearBtn.UseVisualStyleBackColor = true;
this.userPortClearBtn.Click += new System.EventHandler(this.userPortClearBtn_Click);
//
// userPortOpenCloseBtn
//
this.userPortOpenCloseBtn.Dock = System.Windows.Forms.DockStyle.Fill;
this.userPortOpenCloseBtn.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.userPortOpenCloseBtn.Location = new System.Drawing.Point(157, 3);
this.userPortOpenCloseBtn.Name = "userPortOpenCloseBtn";
this.userPortOpenCloseBtn.Size = new System.Drawing.Size(72, 36);
this.userPortOpenCloseBtn.TabIndex = 3;
this.userPortOpenCloseBtn.Text = "打开";
this.userPortOpenCloseBtn.UseVisualStyleBackColor = true;
this.userPortOpenCloseBtn.Click += new System.EventHandler(this.userPortOpenCloseBtn_Click);
//
// userPortShowHex
//
this.userPortShowHex.AutoSize = true;
this.userPortShowHex.Dock = System.Windows.Forms.DockStyle.Fill;
this.userPortShowHex.Location = new System.Drawing.Point(3, 45);
this.userPortShowHex.Name = "userPortShowHex";
this.userPortShowHex.Size = new System.Drawing.Size(148, 36);
this.userPortShowHex.TabIndex = 5;
this.userPortShowHex.Text = "十六进制显示";
this.userPortShowHex.UseVisualStyleBackColor = true;
//
// UserPortRecvCountLabel
//
this.UserPortRecvCountLabel.AutoSize = true;
this.UserPortRecvCountLabel.Dock = System.Windows.Forms.DockStyle.Fill;
this.UserPortRecvCountLabel.Location = new System.Drawing.Point(3, 689);
this.UserPortRecvCountLabel.Margin = new System.Windows.Forms.Padding(3);
this.UserPortRecvCountLabel.Name = "UserPortRecvCountLabel";
this.UserPortRecvCountLabel.Size = new System.Drawing.Size(232, 34);
this.UserPortRecvCountLabel.TabIndex = 7;
this.UserPortRecvCountLabel.Text = "接收: 0 B";
//
// 内存DumpGroup
//
this.DumpGroup.Controls.Add(this.DumpLayout);
this.DumpGroup.Dock = System.Windows.Forms.DockStyle.Fill;
this.DumpGroup.Location = new System.Drawing.Point(1086, 3);
this.DumpGroup.Name = "内存DumpGroup";
this.DumpGroup.Size = new System.Drawing.Size(374, 750);
this.DumpGroup.TabIndex = 8;
this.DumpGroup.TabStop = false;
this.DumpGroup.Text = "内存DUMP";
//
// 内存DumpLayout
//
this.DumpLayout.ColumnCount = 1;
this.DumpLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.DumpLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.DumpLayout.Controls.Add(this., 0, 2);
this.DumpLayout.Controls.Add(this.Layout, 0, 0);
this.DumpLayout.Controls.Add(this.DUMP内存, 0, 1);
this.DumpLayout.Dock = System.Windows.Forms.DockStyle.Fill;
this.DumpLayout.Location = new System.Drawing.Point(3, 21);
this.DumpLayout.Name = "内存DumpLayout";
this.DumpLayout.RowCount = 3;
this.DumpLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 85F));
this.DumpLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 40F));
this.DumpLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.DumpLayout.Size = new System.Drawing.Size(368, 726);
this.DumpLayout.TabIndex = 1;
//
// 内存内容
//
this..Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this..Font = new System.Drawing.Font("Consolas", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this..ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(192)))));
this..Location = new System.Drawing.Point(3, 128);
this..Multiline = true;
this..Name = "内存内容";
this..ReadOnly = true;
this..ScrollBars = System.Windows.Forms.ScrollBars.Both;
this..Size = new System.Drawing.Size(362, 595);
this..TabIndex = 6;
//
// 地址长度指定Layout
//
this.Layout.ColumnCount = 2;
this.Layout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.Layout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.Layout.Controls.Add(this., 1, 0);
this.Layout.Controls.Add(this., 1, 1);
this.Layout.Controls.Add(this.Title, 0, 1);
this.Layout.Controls.Add(this.Title, 0, 0);
this.Layout.Dock = System.Windows.Forms.DockStyle.Fill;
this.Layout.Location = new System.Drawing.Point(3, 3);
this.Layout.Name = "地址长度指定Layout";
this.Layout.RowCount = 2;
this.Layout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.Layout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.Layout.Size = new System.Drawing.Size(362, 79);
this.Layout.TabIndex = 0;
//
// 起始地址
//
this..Dock = System.Windows.Forms.DockStyle.Fill;
this..Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this..Location = new System.Drawing.Point(186, 5);
this..Margin = new System.Windows.Forms.Padding(5);
this..Name = "起始地址";
this..Size = new System.Drawing.Size(171, 28);
this..TabIndex = 4;
this..Text = "00010000";
this..TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// 长度
//
this..Dock = System.Windows.Forms.DockStyle.Fill;
this..Font = new System.Drawing.Font("宋体", 10.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this..Location = new System.Drawing.Point(186, 44);
this..Margin = new System.Windows.Forms.Padding(5);
this..Name = "长度";
this..Size = new System.Drawing.Size(171, 28);
this..TabIndex = 3;
this..Text = "80";
this..TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// 长度Title
//
this.Title.AutoSize = true;
this.Title.Dock = System.Windows.Forms.DockStyle.Fill;
this.Title.Location = new System.Drawing.Point(3, 39);
this.Title.Name = "长度Title";
this.Title.Size = new System.Drawing.Size(175, 40);
this.Title.TabIndex = 2;
this.Title.Text = "长度(16进制):";
this.Title.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// 起始地址Title
//
this.Title.AutoSize = true;
this.Title.Dock = System.Windows.Forms.DockStyle.Fill;
this.Title.Location = new System.Drawing.Point(3, 0);
this.Title.Name = "起始地址Title";
this.Title.Size = new System.Drawing.Size(175, 39);
this.Title.TabIndex = 0;
this.Title.Text = "起始地址(16进制)";
this.Title.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// DUMP内存
//
this.DUMP内存.Dock = System.Windows.Forms.DockStyle.Fill;
this.DUMP内存.Location = new System.Drawing.Point(3, 88);
this.DUMP内存.Name = "DUMP内存";
this.DUMP内存.Size = new System.Drawing.Size(362, 34);
this.DUMP内存.TabIndex = 1;
this.DUMP内存.Text = "DUMP内存";
this.DUMP内存.UseVisualStyleBackColor = true;
this.DUMP内存.Click += new System.EventHandler(this.DUMP内存_Click);
//
// serialPort
//
this.serialPort.BaudRate = 115200;
this.serialPort.ReadTimeout = 50;
this.serialPort.WriteTimeout = 300;
this.serialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort_DataReceived);
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1463, 756);
this.Controls.Add(this.MainLayout);
this.Name = "MainForm";
this.Text = "USTCRVSoC 辅助工具";
this.compileGroup.ResumeLayout(false);
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
this.HexStreamGroup.ResumeLayout(false);
this.tableLayoutPanel4.ResumeLayout(false);
this.tableLayoutPanel4.PerformLayout();
this.tableLayoutPanel5.ResumeLayout(false);
this.tableLayoutPanel6.ResumeLayout(false);
this.bootAddrGroup.ResumeLayout(false);
this.bootAddrGroup.PerformLayout();
this.MainLayout.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.groupBox1.ResumeLayout(false);
this.tableLayoutPanel7.ResumeLayout(false);
this.tableLayoutPanel7.PerformLayout();
this.tableLayoutPanel8.ResumeLayout(false);
this.tableLayoutPanel8.PerformLayout();
this.DumpGroup.ResumeLayout(false);
this.DumpLayout.ResumeLayout(false);
this.DumpLayout.PerformLayout();
this.Layout.ResumeLayout(false);
this.Layout.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TextBox fileSelectionText;
private System.Windows.Forms.Button fileSelectionBtn;
private System.Windows.Forms.GroupBox compileGroup;
private System.Windows.Forms.TextBox compilePromptText;
private System.Windows.Forms.TextBox codeText;
private System.Windows.Forms.Button saveBtn;
private System.Windows.Forms.GroupBox HexStreamGroup;
private System.Windows.Forms.TableLayoutPanel MainLayout;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.Button otherSaveBtn;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5;
private System.Windows.Forms.Button saveVerilog;
private System.Windows.Forms.Button compileBtn;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel6;
private System.Windows.Forms.Button programBtn;
private System.Windows.Forms.ComboBox portSelectionBox;
private System.Windows.Forms.TextBox binText;
private System.IO.Ports.SerialPort serialPort;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox bootAddrGroup;
private System.Windows.Forms.TextBox bootAddrTextBox;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel7;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel8;
private System.Windows.Forms.Button userPortOpenCloseBtn;
private System.Windows.Forms.TextBox userPortTextBox;
private System.Windows.Forms.Button userPortClearBtn;
private System.Windows.Forms.CheckBox userPortShowHex;
private System.Windows.Forms.Label UserPortRecvCountLabel;
private System.Windows.Forms.GroupBox DumpGroup;
private System.Windows.Forms.TableLayoutPanel DumpLayout;
private System.Windows.Forms.TextBox ;
private System.Windows.Forms.TableLayoutPanel Layout;
private System.Windows.Forms.TextBox ;
private System.Windows.Forms.TextBox ;
private System.Windows.Forms.Label Title;
private System.Windows.Forms.Label Title;
private System.Windows.Forms.Button DUMP内存;
}
}

View File

@ -1,559 +0,0 @@
using System;
using System.IO;
using System.IO.Ports;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace USTCRVSoC_tool
{
public partial class MainForm : Form
{
private const string RISCV_TOOLS_PATH = ".\\riscv32-elf-tools-windows\\"; // RISC-V工具链的路径
#region
private uint _userPortCount;
private uint userPortCount // 接收字节数计数属性
{
get
{
return _userPortCount;
}
set
{
_userPortCount = value;
changeCountText(String.Format("接收: {0:D} B", _userPortCount));
}
}
#endregion
public MainForm() // 窗体构造函数
{
InitializeComponent();
InitializeCurrentPort(null, null);
}
#region
private void InitializeCurrentPort(object sender, EventArgs e)
{
string[] ports = SerialPort.GetPortNames();
portSelectionBox.Items.Clear();
portSelectionBox.Items.AddRange(ports);
if (portSelectionBox.Items.Count > 0)
{
portSelectionBox.SelectedIndex = 0;
}
else
{
compilePromptText.Text = "未找到串口,请插入设备,或者检查串口驱动是否安装";
}
}
#endregion
#region
private void fileSelectionBtn_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = ".\\"; //注意这里写路径时要用c:\\而不是c:\
openFileDialog.Filter = "汇编语言文件|*.S";
openFileDialog.RestoreDirectory = true;
openFileDialog.FilterIndex = 1;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
fileSelectionText.Text = openFileDialog.FileName;
try
{
codeText.Text = System.IO.File.ReadAllText(openFileDialog.FileName);
compilePromptText.Text = "已打开文件";
saveBtn.Enabled = true;
}
catch (Exception ex)
{
compilePromptText.Text = "打开文件失败\n " + ex.Message;
}
}
}
private void saveBtn_Click(object sender, EventArgs e)
{
try
{
System.IO.File.WriteAllText(fileSelectionText.Text, codeText.Text);
compilePromptText.Text = " 已保存文件";
}
catch (Exception ex)
{
compilePromptText.Text = " 保存文件失败\r\n" + ex.Message;
}
}
private void otherSaveBtn_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.InitialDirectory = ".\\"; //注意这里写路径时要用c:\\而不是c:\
saveFileDialog.Filter = "汇编语言文件|*.S";
saveFileDialog.RestoreDirectory = true;
saveFileDialog.FilterIndex = 1;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
fileSelectionText.Text = saveFileDialog.FileName;
try
{
System.IO.File.WriteAllText(fileSelectionText.Text, codeText.Text);
compilePromptText.Text = "已保存文件";
}
catch (Exception ex)
{
compilePromptText.Text = "保存文件失败\n " + ex.Message;
}
}
}
#endregion
#region
public bool RunCmd(string path, string command, ref string msg) // 调用 CMD 运行一个命令
{
try
{
msg = ">" + command + "\r\n\r\n";
System.Diagnostics.Process pro = new System.Diagnostics.Process();
pro.StartInfo.FileName = "cmd.exe";
pro.StartInfo.CreateNoWindow = true; // 不创建新窗口
pro.StartInfo.UseShellExecute = false; // 不启用shell启动进程
pro.StartInfo.RedirectStandardInput = true; // 重定向输入
pro.StartInfo.RedirectStandardOutput = true; // 重定向标准输出
pro.StartInfo.RedirectStandardError = true;
pro.StartInfo.StandardErrorEncoding = System.Text.UTF8Encoding.UTF8;
pro.StartInfo.StandardOutputEncoding = System.Text.UTF8Encoding.UTF8; // 重定向错误输出
pro.StartInfo.WorkingDirectory = path;
pro.Start(); //开启cmd
pro.StandardInput.WriteLine(command);
pro.StandardInput.AutoFlush = true;
pro.StandardInput.WriteLine("exit"); //若是运行时间短可加入此命令
pro.WaitForExit();//若运行时间长,使用这个,等待程序执行完退出进程
string errorStr = pro.StandardError.ReadToEnd();
msg += errorStr;
pro.Close();
return errorStr.Trim().Length == 0;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message + "\r\n请确保工具链目录与本程序在同一目录下");
return false;
}
}
private string dumpBin(string bin_file_path) // 读取汇编出的.bin 文件并调整字节序、转换为一行一行的指令
{
StringBuilder strbuild = new StringBuilder();
byte[] bin = System.IO.File.ReadAllBytes(bin_file_path);
for (int i = 0; i < bin.Length - 3; i += 4)
{
for (int j = 3; j >= 0; j--)
strbuild.Append(bin[i + j].ToString("x2"));
strbuild.AppendLine();
}
return strbuild.ToString();
}
private void compileBtn_Click(object sender, EventArgs e) // 点击“汇编”按钮时完成一系列CMD命令并把编译结果读入到 binText 这个控件里
{
bool stat;
string msg = "";
string asm_command = "riscv32-elf-as " + fileSelectionText.Text + " -o compile_tmp.o -march=rv32im";
string ld_command = "riscv32-elf-ld compile_tmp.o -o compile_tmp.om";
compilePromptText.Clear();
try
{
System.IO.File.WriteAllText(fileSelectionText.Text, codeText.Text);
}
catch (Exception ex)
{
compilePromptText.Text = "保存文件失败\n " + ex.Message;
return;
}
stat = RunCmd(RISCV_TOOLS_PATH, asm_command, ref msg);
compilePromptText.AppendText(msg);
if (!stat)
{
compilePromptText.AppendText(" *** 编译出错! ***");
return;
}
stat = RunCmd(RISCV_TOOLS_PATH, ld_command, ref msg);
compilePromptText.AppendText(msg);
if (!stat)
{
compilePromptText.AppendText(" *** 生成om文件出错! ***");
return;
}
stat = RunCmd(RISCV_TOOLS_PATH, "del compile_tmp.o", ref msg);
compilePromptText.AppendText(msg);
if (!stat)
{
compilePromptText.AppendText(" *** 删除中间文件出错! ***");
return;
}
stat = RunCmd(RISCV_TOOLS_PATH, "riscv32-elf-objcopy -O binary compile_tmp.om compile_tmp.bin", ref msg);
compilePromptText.AppendText(msg);
if (!stat)
{
compilePromptText.AppendText(" *** 生成bin文件出错! ***");
return;
}
stat = RunCmd(RISCV_TOOLS_PATH, "del compile_tmp.om", ref msg);
compilePromptText.AppendText(msg);
if (!stat)
{
compilePromptText.AppendText(" *** 删除中间文件出错! ***");
return;
}
try
{
binText.Text = dumpBin(RISCV_TOOLS_PATH + "compile_tmp.bin");
compilePromptText.AppendText(" *** 编译完成! ***");
}
catch
{
compilePromptText.AppendText(" *** 读取bin文件出错! ***");
return;
}
}
#endregion
#region Verilog InstrROM
private const string VerilogHead = "module instr_rom(\n input logic clk, rst_n,\n naive_bus.slave bus\n);\nlocalparam INSTR_CNT = 30'd";
private const string VerilogMid = ";\nwire [0:INSTR_CNT-1] [31:0] instr_rom_cell = {\n";
private const string VerilogTail = "};\n\nlogic [29:0] cell_rd_addr;\n\nassign bus.rd_gnt = bus.rd_req;\nassign bus.wr_gnt = bus.wr_req;\nassign cell_rd_addr = bus.rd_addr[31:2];\nalways @ (posedge clk or negedge rst_n)\n if(~rst_n)\n bus.rd_data <= 0;\n else begin\n if(bus.rd_req)\n bus.rd_data <= (cell_rd_addr>=INSTR_CNT) ? 0 : instr_rom_cell[cell_rd_addr];\n else\n bus.rd_data <= 0;\n end\n\nendmodule\n\n";
private string genVerilogRom()
{
StringBuilder strBuilder = new StringBuilder();
int index = 0;
string[] lines = binText.Text.Trim().Split();
for (int idx = 0; idx < lines.Length; idx++)
{
string line = lines[idx];
string hex_num = line.Trim();
if (hex_num.Length <= 0)
continue;
if (idx < lines.Length - 2)
strBuilder.Append(String.Format(" 32'h{1:S}, // 0x{0:x8}\n", index * 4, hex_num));
else
strBuilder.Append(String.Format(" 32'h{1:S} // 0x{0:x8}\n", index * 4, hex_num));
index += 1;
}
strBuilder.Insert(0, VerilogMid);
strBuilder.Insert(0, index.ToString());
strBuilder.Insert(0, VerilogHead);
strBuilder.Append(VerilogTail);
return strBuilder.ToString();
}
private void saveVerilog_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.InitialDirectory = ".\\"; //注意这里写路径时要用c:\\而不是c:\
saveFileDialog.Filter = "SystemVerilog源文件|*.sv";
saveFileDialog.RestoreDirectory = true;
saveFileDialog.FilterIndex = 1;
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
try
{
System.IO.File.WriteAllText(saveFileDialog.FileName, genVerilogRom());
compilePromptText.Text = "已保存 Verilog ROM 文件";
}
catch (Exception ex)
{
compilePromptText.Text = "保存 Verilog ROM 文件失败\r\n" + ex.Message;
}
}
}
#endregion
#region
private bool serialSessionA(string send, ref string response) // 发送一个命令并得到响应字符串
{
return serialSessionTry(send, ref response, "");
}
private bool serialSessionB(string send, string respectResponse) // 发送一个命令并等待指定的响应字符串到来
{
string response = "";
return serialSessionTry(send, ref response, respectResponse);
}
private bool serialSessionTry(string send, ref string response, string respectResponse, int try_time = 3) // 多次请求全部失败时,返回失败,否则返回成功
{
for (int i = 0; i < try_time; i++)
{
try { serialPort.ReadExisting(); }// 清空接收缓冲区
catch { }
if (serialSend(send))
{
if (serialRead(ref response, respectResponse))
return true;
}
}
compilePromptText.AppendText(" *** 串口调试多次尝试失败 ***\r\n");
return false;
}
private bool serialSend(string send)
{
compilePromptText.AppendText("send: " + send);
try
{
serialPort.Write(send + "\n");
}
catch (Exception ex)
{
compilePromptText.AppendText(" " + ex.Message + "\r\n");
return false;
}
return true;
}
private bool serialRead(ref string response, string respectResponse)
{
try
{
for (int i = 0; i < 8; i++)
{
response = serialPort.ReadLine().Trim();
bool is_respect = respectResponse.Equals("") || respectResponse.Equals(response);
if (is_respect)
{
compilePromptText.AppendText(" response: " + response + "\r\n");
return true;
}
}
}
catch (Exception ex)
{
compilePromptText.AppendText(" " + ex.Message + "\r\n");
return false;
}
compilePromptText.AppendText(" response: *** 超时 ***\r\n" + response);
return false;
}
#endregion
#region
private bool refreshSerial()
{
if (serialPort.IsOpen)
serialPort.Close();
try
{
serialPort.PortName = portSelectionBox.Text;
serialPort.Open();
}
catch (Exception ex)
{
compilePromptText.AppendText(" *** 打开串口出错 ***\r\n " + ex.Message);
refreshPortStatus();
return false;
}
return true;
}
private void refreshPortStatus()
{
if (serialPort.IsOpen)
userPortOpenCloseBtn.Text = "关闭";
else
userPortOpenCloseBtn.Text = "打开";
}
private void userPortOpenCloseBtn_Click(object sender, EventArgs e)
{
if (userPortOpenCloseBtn.Text == "打开")
{
compilePromptText.Clear();
refreshSerial();
serialSessionB("s", "debug");
serialSessionB("o", "user");
}
else
{
serialPort.Close();
}
refreshPortStatus();
}
#endregion
#region
private void programBtn_Click(object sender, EventArgs e) // 烧录程序
{
enableUartDisplay = false;
userPortTextBox.Clear();
compilePromptText.Clear();
uint boot_addr;
try
{
boot_addr = Convert.ToUInt32(bootAddrTextBox.Text, 16);
}
catch (Exception ex)
{
compilePromptText.AppendText(" *** Boot Addr格式有误 ***\r\n " + ex.Message);
return;
}
if (!refreshSerial())
return;
if (!serialSessionB("s", ""))
return;
uint index = 0;
foreach (string line in binText.Text.Split())
{
string hex_num = line.Trim();
if (hex_num.Length <= 0)
continue;
string send_str = String.Format("{0:x8} {1:S}", boot_addr + index * 4, hex_num);
index++;
if (!serialSessionB(send_str, "wr done"))
return;
}
if (!serialSessionB(string.Format("r{0:x8}", boot_addr), "rst done"))
return;
compilePromptText.AppendText(" *** 烧录完成 ***\r\n");
try { serialPort.ReadExisting(); }// 清空接收缓冲区
catch { }
userPortTextBox.Clear();
enableUartDisplay = true;
}
#endregion
#region DUMP内存
private void DUMP内存_Click(object sender, EventArgs e) // 查看内存
{
enableUartDisplay = false;
userPortTextBox.Clear();
compilePromptText.Clear();
uint start, len;
try
{
start = Convert.ToUInt32(.Text, 16);
len = Convert.ToUInt32(.Text, 16);
}
catch (Exception ex)
{
compilePromptText.AppendText(" *** 起始地址格式有误 ***\r\n " + ex.Message);
return;
}
start = 4 * (start / 4); // 起始地址自动与4对齐
if (len > 0x1000)
{
compilePromptText.AppendText(" *** 长度不能大于0x1000 ***\r\n ");
return;
}
len /= 4;
if (!refreshSerial())
return;
string response = "";
if (!serialSessionB("s", ""))
return;
.Clear();
uint index = 0;
for (index = 0; index < len; index++)
{
string send_str = String.Format("{0:x8}", start + index * 4);
response = "";
if (!serialSessionA(send_str, ref response))
return;
.AppendText(String.Format("{0:x8} : {1:S}\r\n", start + index * 4, response.Trim()));
}
serialSessionB("o", "user");
compilePromptText.AppendText(" *** Dump内存完成 ***\r\n");
try { serialPort.ReadExisting(); }// 清空接收缓冲区
catch { }
userPortTextBox.Clear();
enableUartDisplay = true;
}
#endregion
#region
bool enableUartDisplay = true;
public delegate void changeTextHandler(object str);
private void appendUserPortText(object str)
{
if (userPortTextBox.InvokeRequired == true)
{
changeTextHandler ct = new changeTextHandler(appendUserPortText);
userPortTextBox.Invoke(ct, new object[] { str });
}
else
{
userPortTextBox.AppendText(str.ToString());
}
}
private void changeCountText(object str)
{
if (UserPortRecvCountLabel.InvokeRequired == true)
{
changeTextHandler ct = new changeTextHandler(changeCountText);
UserPortRecvCountLabel.Invoke(ct, new object[] { str });
}
else
{
UserPortRecvCountLabel.Text = str.ToString();
}
}
private void userPortClearBtn_Click(object sender, EventArgs e)
{
userPortTextBox.Clear();
}
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
if (enableUartDisplay)
{
SerialPort sp = (SerialPort)sender;
try
{
string recvdata = sp.ReadExisting();
if (userPortShowHex.Checked)
{
StringBuilder sb = new StringBuilder();
foreach (byte ch in recvdata)
{
sb.Append(String.Format("{0:X2} ", ch));
}
appendUserPortText(sb.ToString());
}
else
{
appendUserPortText(recvdata);
}
userPortCount += (uint)recvdata.Length;
}
catch { }
}
}
#endregion
private void tableLayoutPanel6_Paint(object sender, PaintEventArgs e)
{
}
}
}

View File

@ -1,123 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="serialPort.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace USTCRVSoC_tool
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}

View File

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("programming_asm")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("programming_asm")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("b3ab6819-a056-4340-86b3-edae79aaab47")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -1,63 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace USTCRVSoC_tool.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("USTCRVSoC_tool.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 使用此强类型资源类,为所有资源查找
/// 重写当前线程的 CurrentUICulture 属性。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1,26 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace USTCRVSoC_tool.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@ -1,7 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -1,99 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{54C41CBE-83B8-44F7-ABCB-85F543A690CC}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>USTCRVSoC_tool</RootNamespace>
<AssemblyName>USTCRVSoC-tool</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>chip.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Content Include="chip.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

View File

@ -1,20 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UartSession", "UartSession\UartSession.csproj", "{90E1C916-2A9E-43DC-A0A4-56D029F666C2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{90E1C916-2A9E-43DC-A0A4-56D029F666C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{90E1C916-2A9E-43DC-A0A4-56D029F666C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{90E1C916-2A9E-43DC-A0A4-56D029F666C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{90E1C916-2A9E-43DC-A0A4-56D029F666C2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

View File

@ -1,110 +0,0 @@
using System;
using System.IO.Ports;
namespace UartSession
{
class Program
{
static SerialPort port = new SerialPort();
static void DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
try
{
string recvdata = sp.ReadExisting();
Console.Write(recvdata);
}
catch { }
}
static void Main(string[] args)
{
int index;
string input;
port.BaudRate = 115200;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.DtrEnable = false;
port.RtsEnable = false;
port.ReadTimeout = 1000;
port.WriteTimeout = 500;
port.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
while (true)
{
int set_baud = -1;
int ser_no = -1;
string[] ser_names = { };
Console.WriteLine("\n\n命令列表:");
try { ser_names = SerialPort.GetPortNames(); }catch { }
for (index = 0; index < ser_names.Length; index++)
Console.WriteLine(" {0:#0} : 打开 {1:S}", index, ser_names[index]);
if(index<=0)
Console.WriteLine(" (* 未找到端口 *)");
Console.WriteLine(" baud [数字] : 设置COM口波特率例如 baud 9600 表示设置波特率为9600");
Console.WriteLine(" refresh : 刷新COM口列表");
Console.WriteLine(" exit : 退出");
Console.Write("\n当前波特率为{0:D}\n请输入你的命令:", port.BaudRate);
input = Console.ReadLine().Trim();
try { ser_no = Convert.ToInt32(input); } catch {}
try{
string[] tmps = input.Split();
if (tmps.Length == 2 && tmps[0] == "baud")
set_baud = Convert.ToInt32(tmps[1]);
}catch{}
if (input == "exit")
break;
else if (input == "refresh")
{
Console.WriteLine("\n\n");
continue;
}
else if (set_baud>0)
{
try
{
port.BaudRate = set_baud;
}
catch (Exception ex)
{
Console.WriteLine(" *** 错误: {0:S} ***", ex.Message);
continue;
}
}
else if (ser_no >= 0 && ser_no < index)
{
string ser_name = ser_names[ser_no];
try
{
port.PortName = ser_name;
port.Open();
}
catch (Exception ex)
{
Console.WriteLine(" *** 开启串口错误: {0:S} ***", ex.Message);
continue;
}
Console.WriteLine(" 已经打开{0:S}请输入发送数据输入exit退出", ser_name);
while (true)
{
input = Console.ReadLine().Trim();
if (input == "exit")
break;
try { port.WriteLine(input); }
catch { }
}
port.Close();
break;
}
else
Console.WriteLine(" *** 格式错误 ***");
}
}
}
}

View File

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("UartSession")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UartSession")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("03cfee7d-74be-4491-8eff-8f2b5393d25d")]
// 程序集的版本信息由下面四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

View File

@ -1,64 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{90E1C916-2A9E-43DC-A0A4-56D029F666C2}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>UartSession</RootNamespace>
<AssemblyName>UartSession</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>USB.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Content Include="USB.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

BIN
figures/CPU.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
figures/DE0-Nano.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
figures/SoC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
figures/USTCRVSoC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
figures/UartSession1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
figures/UartSession2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
figures/UartSession3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
figures/vga_show.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

View File

@ -1,13 +0,0 @@
/* Quartus II 64-Bit Version 13.1.0 Build 162 10/23/2013 SJ Full Version */
JedecChain;
FileRevision(JESD32A);
DefaultMfr(6E);
P ActionCode(Cfg)
Device PartName(EP4CE22F17) Path("E:/work-Lab/USTCRVSoC/hardware/Quartus/DE0Nano_USTCRVSoC/output_files/") File("DE0Nano_USTCRVSoC.sof") MfrSpec(OpMask(1));
ChainEnd;
AlteraBegin;
ChainType(JTAG);
AlteraEnd;

View File

@ -1,8 +0,0 @@
<sld_project_info>
<project>
<hash md5_digest_80b="cefaa24b22dc0d7c5813"/>
</project>
<file_info>
<file device="EP4CE22F17C6" path="DE0Nano_USTCRVSoC.sof" usercode="0xFFFFFFFF"/>
</file_info>
</sld_project_info>

View File

@ -1,9 +0,0 @@
# USTCRVSoC 硬件
* RTL 目录中是 SoC 全部的 SystemVerilog 代码。
* Quartus 目录中是基于 Altera FPGA 的工程,目前有 DE0-Nano 开发板。
* Vivado 目录中是基于 Xilinx FPGA 的工程,目前有 Arty-7 开发板和 Nexys4 开发板。
* Simulation_SoC 目录是对整个 SoC 的仿真工程
* Simulation_RiscvCPU 目录是对 RiscV-CPU 进行的指令集测试仿真使用RiscV官方测试
请注意,所有工程共用 ./RTL 目录,因此在一个工程里修改 SoC 代码也会导致其它工程中的代码发生变化

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +0,0 @@
module dual_read_port_ram_32x32( // 32bit*32addr
input logic clk,
input logic i_we,
input logic [ 4:0] i_waddr,
input logic [31:0] i_wdata,
input logic [ 4:0] i_raddr1,
output logic [31:0] o_rdata1,
input logic [ 4:0] i_raddr2,
output logic [31:0] o_rdata2
);
initial begin o_rdata1 = 0; o_rdata2 = 0; end
logic [31:0] data_ram_cell [0:31];
always @ (posedge clk)
o_rdata1 <= data_ram_cell[i_raddr1];
always @ (posedge clk)
o_rdata2 <= data_ram_cell[i_raddr2];
always @ (posedge clk)
if(i_we)
data_ram_cell[i_waddr] <= i_wdata;
endmodule

View File

@ -1,19 +0,0 @@
module ram128B( // 128B
input logic clk,
input logic i_we,
input logic [ 6:0] i_addr,
input logic [ 7:0] i_wdata,
output logic [ 7:0] o_rdata
);
initial o_rdata = 8'h0;
logic [7:0] data_ram_cell [0:127];
always @ (posedge clk)
o_rdata <= data_ram_cell[i_addr];
always @ (posedge clk)
if(i_we)
data_ram_cell[i_addr] <= i_wdata;
endmodule

View File

@ -1,188 +0,0 @@
module vga_char_86x32 #(
parameter VGA_CLK_DIV = 1
)(
// clock
input logic clk, rst_n,
// vga interfaces
output logic hsync, vsync,
output logic red, green, blue,
// user interface
output logic req,
output logic [11:0] addr,
input logic [ 7:0] ascii
);
localparam H_END = 10'd688,
H_BRSTART = H_END + 10'd4 ,
H_BREND = H_BRSTART + 10'd30 ,
H_SYNCSTART = H_BREND + 10'd25 ,
H_SYNCEND = H_SYNCSTART + 10'd128,
H_BLSTART = H_SYNCEND + 10'd89 ,
H_BLEND = H_BLSTART + 10'd30 ,
H_PERIOD = H_BLEND + 10'd4 ,
V_END = 10'd512,
V_BRSTART = V_END + 10'd4 ,
V_BREND = V_BRSTART + 10'd30 ,
V_SYNCSTART = V_BREND + 10'd38 ,
V_SYNCEND = V_SYNCSTART + 10'd4 ,
V_BLSTART = V_SYNCEND + 10'd66 ,
V_BLEND = V_BLSTART + 10'd30 ,
V_PERIOD = V_BLEND + 10'd4 ;
logic [3:0] rlp=4'h0, clp=4'h0, hsp=4'h0, vsp=4'h0;
logic vlbr=1'b0, vgbl=1'b0, vlbl=1'b0, vgbr=1'b0, hlbr=1'b0, hgbl=1'b0, hlbl=1'b0, hgbr=1'b0;
logic vir=1'b0, hir=1'b0, vbr=1'b0, hbr=1'b0, vbl=1'b0, hbl=1'b0, hb=1'b0, vb=1'b0, border=1'b0;
logic [9:0] cnt = 0, hcnt = 0, vcnt = 0;
logic req1 = 1'b0, req2 = 1'b0;
logic [7:0] ascii_bufferout, ascii_latch=8'h0, ascii_to_rom;
logic [7:0] rom_data;
logic [6:0] x_h, x_h1=7'h0, x_h2=7'h0;
logic [5:0] y_h;
logic [2:0] x_l, x_l1 = 3'h0, x_l2 = 3'h0, x_l3 = 3'h0, x_l4 = 3'h0;
logic [3:0] y_l, y_l1 = 4'h0, y_l2 = 4'h0, y_l3 = 4'h0;
assign {x_h, x_l} = hcnt;
assign {y_h, y_l} = vcnt;
initial begin hsync=1'b0; vsync=1'b0; {red,green,blue}=3'h0; req=1'b0; addr = 12'h0; end
always @ (posedge clk)
if(~rst_n) begin
vlbr<= 1'b0;
vgbl<= 1'b0;
vlbl<= 1'b0;
vgbr<= 1'b0;
hlbr<= 1'b0;
hgbl<= 1'b0;
hlbl<= 1'b0;
hgbr<= 1'b0;
vir <= 1'b0;
hir <= 1'b0;
vbr <= 1'b0;
hbr <= 1'b0;
vbl <= 1'b0;
hbl <= 1'b0;
hb <= 1'b0;
vb <= 1'b0;
border <= 1'b0;
end else begin
vlbr<= vcnt < V_BREND ;
vgbl<= vcnt >= V_BLSTART;
vlbl<= vcnt < V_BLEND ;
vgbr<= vcnt >= V_BRSTART;
hlbr<= hcnt < H_BREND ;
hgbl<= hcnt >= H_BLSTART;
hlbl<= hcnt < H_BLEND;
hgbr<= hcnt >= H_BRSTART;
vir <= vlbr | vgbl;
hir <= hlbr | hgbl;
vbr <= vgbr & vlbr;
hbr <= hgbr & hlbr;
vbl <= vgbl & vlbl;
hbl <= hgbl & hlbl;
hb <= (hbr | hbl) & vir;
vb <= (vbr | vbl) & hir;
border <= hb | vb;
end
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
cnt <= 10'h0;
hcnt <= 10'h0;
vcnt <= 10'h0;
end else begin
cnt <= (cnt<(VGA_CLK_DIV-1)) ? cnt + 10'h1 : 10'h0;
if(cnt==10'h0) begin
if(hcnt < H_PERIOD) begin
hcnt <= hcnt + 10'h1;
end else begin
hcnt <= 10'h0;
vcnt <= (vcnt<V_PERIOD) ? vcnt + 10'h1 : 10'h0;
end
end
end
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
req <= 1'b0;
req1<= 1'b0;
req2<= 1'b0;
end else begin
req <= cnt==10'h0 && hcnt<H_END && vcnt<V_END && x_l==3'h0 && y_l==4'h0;
req1<= req;
req2<= req1;
end
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
clp <= 4'h0;
rlp <= 4'h0;
hsp <= 4'h0;
vsp <= 4'h0;
end else begin
clp <= {clp[2:0], ( cnt==10'h0 ) };
rlp <= {rlp[2:0], ( hcnt<H_END && vcnt<V_END ) };
hsp <= {hsp[2:0], ( hcnt>=H_SYNCSTART && hcnt<H_SYNCEND ) };
vsp <= {vsp[2:0], ( vcnt>=V_SYNCSTART && vcnt<V_SYNCEND ) };
end
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
addr <= 12'h0;
end else begin
if( cnt==10'h0 && hcnt<H_END && vcnt<V_END ) begin
addr <= {y_h[4:0],x_h};
end else begin
addr <= 12'h0;
end
end
always @ (posedge clk or negedge rst_n)
if(~rst_n)
{x_l1, y_l1, x_l2, y_l2, x_l3, y_l3, x_l4, x_h1, x_h2} <= 38'h0;
else
{x_l1, y_l1, x_l2, y_l2, x_l3, y_l3, x_l4, x_h1, x_h2} <= {x_l, y_l, x_l1, y_l1, x_l2, y_l2, x_l3, x_h, x_h1};
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
hsync <= 1'b0;
vsync <= 1'b0;
{red,green,blue} <= 3'h0;
end else begin
if(clp[3]) begin
hsync <= ~hsp[3];
vsync <= ~vsp[3];
if(rlp[3])
{red,green,blue} <= {3{rom_data[x_l4]}};
else if(border)
{red,green,blue} <= 3'b100;
else
{red,green,blue} <= 3'b000;
end
end
always @ (posedge clk or negedge rst_n)
if(~rst_n)
ascii_latch <= 8'h0;
else begin
ascii_latch <= req1 ? ascii : 8'h0;
end
// buffered a line, 86 chars, The goal is to minimize the number of memory accesses
ram128B ram128B_vga_line_buffer_inst( // 128B
.clk ( clk ),
.i_we ( req1 ),
.i_addr ( x_h2 ),
.i_wdata ( ascii ),
.o_rdata ( ascii_bufferout )
);
assign ascii_to_rom = req2 ? ascii_latch : ascii_bufferout;
char8x16_rom char_8x16_rom_inst(
.clk ( clk ),
.addr ( {ascii_to_rom, y_l3} ),
.data ( rom_data )
);
endmodule

View File

@ -1,33 +0,0 @@
version:1
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:626173656469616c6f675f6f6b:32:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:63726561746573726366696c656469616c6f675f66696c655f6e616d65:31:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:63726561746573726366696c656469616c6f675f66696c655f74797065:31:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:6670676163686f6f7365725f667067615f7461626c65:31:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:66696c6573657470616e656c5f66696c655f7365745f70616e656c5f74726565:3139:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:666c6f776e6176696761746f727472656570616e656c5f666c6f775f6e6176696761746f725f74726565:33:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:67657474696e6773746172746564766965775f6372656174655f6e65775f70726f6a656374:31:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:67726170686963616c766965775f7a6f6f6d5f696e:3133:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:67726170686963616c766965775f7a6f6f6d5f6f7574:3436:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:68636f6465656469746f725f7365617263685f746578745f636f6d626f5f626f78:32:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:7061636f6d6d616e646e616d65735f6164645f736f7572636573:34:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:7061636f6d6d616e646e616d65735f6175746f5f7570646174655f68696572:32:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:7061636f6d6d616e646e616d65735f73696d756c6174696f6e5f6c6976655f72657374617274:32:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:7061636f6d6d616e646e616d65735f73696d756c6174696f6e5f6c6976655f72756e:3233:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:7061636f6d6d616e646e616d65735f73696d756c6174696f6e5f72656c61756e6368:3135:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:7061636f6d6d616e646e616d65735f73696d756c6174696f6e5f7265736574:32:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:7061636f6d6d616e646e616d65735f73696d756c6174696f6e5f72756e:31:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:7061636f6d6d616e646e616d65735f73696d756c6174696f6e5f72756e5f6265686176696f72616c:33:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:706176696577735f636f6465:32:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:706176696577735f70726f6a6563745f73756d6d617279:32:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:70726f6a6563746e616d6563686f6f7365725f63686f6f73655f70726f6a6563745f6c6f636174696f6e:32:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:70726f6a6563746e616d6563686f6f7365725f70726f6a6563745f6e616d65:31:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:72646976696577735f77617665666f726d5f766965776572:34:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:73696d756c6174696f6e6f626a6563747370616e656c5f73696d756c6174696f6e5f6f626a656374735f747265655f7461626c65:36:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:73696d756c6174696f6e73636f70657370616e656c5f73696d756c6174655f73636f70655f7461626c65:3130:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:73726363686f6f73657270616e656c5f6164645f68646c5f616e645f6e65746c6973745f66696c65735f746f5f796f75725f70726f6a656374:33:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:73726363686f6f73657270616e656c5f6372656174655f66696c65:31:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:7372636d656e755f69705f686965726172636879:34:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:7461736b62616e6e65725f636c6f7365:31:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:74636c636f6e736f6c65766965775f74636c5f636f6e736f6c655f636f64655f656469746f72:31:00:00
70726f6a656374:76697661646f5f75736167655c6775695f68616e646c657273:77617665666f726d6e616d65747265655f77617665666f726d5f6e616d655f74726565:31:00:00
eof:3134170508

View File

@ -1,8 +0,0 @@
version:1
70726f6a656374:76697661646f5f75736167655c6a6176615f636f6d6d616e645f68616e646c657273:616464736f7572636573:34:00:00
70726f6a656374:76697661646f5f75736167655c6a6176615f636f6d6d616e645f68616e646c657273:6e657770726f6a656374:31:00:00
70726f6a656374:76697661646f5f75736167655c6a6176615f636f6d6d616e645f68616e646c657273:73696d756c6174696f6e72656c61756e6368:3134:00:00
70726f6a656374:76697661646f5f75736167655c6a6176615f636f6d6d616e645f68616e646c657273:73696d756c6174696f6e72657374617274:32:00:00
70726f6a656374:76697661646f5f75736167655c6a6176615f636f6d6d616e645f68616e646c657273:73696d756c6174696f6e72756e:33:00:00
70726f6a656374:76697661646f5f75736167655c6a6176615f636f6d6d616e645f68616e646c657273:73696d756c6174696f6e72756e666f7274696d65:3233:00:00
eof:3163366878

View File

@ -1,3 +0,0 @@
version:1
6d6f64655f636f756e7465727c4755494d6f6465:1
eof:

View File

@ -1,4 +0,0 @@
version:1
7873696d:7873696d5c636f6d6d616e645f6c696e655f6f7074696f6e73:2d73696d5f6d6f6465:6265686176696f72616c:00:00
7873696d:7873696d5c636f6d6d616e645f6c696e655f6f7074696f6e73:2d73696d5f74797065:64656661756c743a3a:00:00
eof:2427094519

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Product Version: Vivado v2018.3 (64-bit) -->
<!-- -->
<!-- Copyright 1986-2018 Xilinx, Inc. All Rights Reserved. -->
<labtools version="1" minor="0"/>

View File

@ -1 +0,0 @@
The files in this directory structure are automatically generated and managed by Vivado. Editing these files is not recommended.

View File

@ -1,72 +0,0 @@
//--------------------------------------------------------------------------------------------------------------
// This project runs RISC-V official ISA test
// see https://github.com/riscv/riscv-tests
//--------------------------------------------------------------------------------------------------------------
`timescale 1ns / 1ns
module tb_core #(
// Specify the instruction&data stream file to be tested here
// We modified RISC-V official ISA test into 3 small tests (In path USTCRVSoC/hardware/Simulation_RiscvCPU/RISCV_RV32I_Test)
// notice: this is the file-path in my computer, dont forget to modify it
parameter INSTRUCTION_STREAM_FILE = "E:\\FPGAcommon\\USTCRVSoC\\hardware\\Simulation_RiscvCPU\\RISCV_RV32I_Test\\testA_InstructionStream.txt"
// "E:\\FPGAcommon\\USTCRVSoC\\hardware\\Simulation_RiscvCPU\\RISCV_RV32I_Test\\testB_InstructionStream.txt"
// "E:\\FPGAcommon\\USTCRVSoC\\hardware\\Simulation_RiscvCPU\\RISCV_RV32I_Test\\testC_InstructionStream.txt"
)();
logic [31:0] ram [4096]; // this ram stores both instruction and data
initial $readmemh(INSTRUCTION_STREAM_FILE, ram);
logic clk = 1'b1, rst_n = 1'b0;
always #5 clk = ~clk; // 100MHz clock
initial #40 rst_n = 1'b1;
naive_bus bus_masters[2]();
naive_bus bus_slaves [1]();
// RV32I Core
core_top core_top_inst(
.clk ( clk ),
.rst_n ( rst_n ),
.i_boot_addr ( 0 ),
.instr_master ( bus_masters[1] ),
.data_master ( bus_masters[0] )
);
naive_bus_router #(
.N_MASTER ( 2 ),
.N_SLAVE ( 1 ),
.SLAVES_MASK ( { 32'h0000_ffff } ),
.SLAVES_BASE ( { 32'h0000_0000 } )
) soc_bus_router_inst (
.clk ( clk ),
.rst_n ( rst_n ),
.masters ( bus_masters ),
.slaves ( bus_slaves )
);
assign bus_slaves[0].rd_gnt = 1'b1;
assign bus_slaves[0].wr_gnt = 1'b1;
always @ (posedge clk or negedge rst_n)
if(~rst_n)
bus_slaves[0].rd_data <= 0;
else
bus_slaves[0].rd_data <= ram[bus_slaves[0].rd_addr[14:2]];
always @ (posedge clk or negedge rst_n)
if(~rst_n) begin
end else begin
if(bus_slaves[0].wr_be[0])
ram[bus_slaves[0].wr_addr[14:2]][ 7: 0] <= bus_slaves[0].wr_data[ 7: 0];
if(bus_slaves[0].wr_be[1])
ram[bus_slaves[0].wr_addr[14:2]][15: 8] <= bus_slaves[0].wr_data[15: 8];
if(bus_slaves[0].wr_be[2])
ram[bus_slaves[0].wr_addr[14:2]][23:16] <= bus_slaves[0].wr_data[23:16];
if(bus_slaves[0].wr_be[3])
ram[bus_slaves[0].wr_addr[14:2]][31:24] <= bus_slaves[0].wr_data[31:24];
end
endmodule

View File

@ -1,13 +0,0 @@
quit -sim
# source files
vlog -sv -incr tb_soc.sv ../../RTL/*.sv
vsim -t ps -voptargs="+acc" work.tb_soc
log -r /*
radix 16
do wave.do
run 20us

Some files were not shown because too many files have changed in this diff Show More