mirror of
https://github.com/WangXuan95/USTC-RVSoC.git
synced 2025-01-30 23:02:55 +08:00
合并ISP-UART和USER-UART,添加Nexys4开发板工程
This commit is contained in:
parent
0840f54aa6
commit
dfb750b8d5
@ -1,30 +0,0 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2013 Altera Corporation
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, Altera MegaCore Function License
|
||||
# Agreement, or other applicable license agreement, including,
|
||||
# without limitation, that your use is for the sole purpose of
|
||||
# programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the
|
||||
# applicable agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II 64-Bit
|
||||
# Version 13.1.0 Build 162 10/23/2013 SJ Full Version
|
||||
# Date created = 10:11:55 February 10, 2019
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
QUARTUS_VERSION = "13.1"
|
||||
DATE = "10:11:55 February 10, 2019"
|
||||
|
||||
# Revisions
|
||||
|
||||
PROJECT_REVISION = "DE0_Nano"
|
@ -1,275 +0,0 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2013 Altera Corporation
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, Altera MegaCore Function License
|
||||
# Agreement, or other applicable license agreement, including,
|
||||
# without limitation, that your use is for the sole purpose of
|
||||
# programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the
|
||||
# applicable agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II 64-Bit
|
||||
# Version 13.1.0 Build 162 10/23/2013 SJ Full Version
|
||||
# Date created = 10:11:56 February 10, 2019
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# 1) The default values for assignments are stored in the file:
|
||||
# DE0_Nano_assignment_defaults.qdf
|
||||
# If this file doesn't exist, see file:
|
||||
# assignment_defaults.qdf
|
||||
#
|
||||
# 2) Altera recommends that you do not modify this file. This
|
||||
# file is updated automatically by the Quartus II software
|
||||
# and any changes you make may be lost or overwritten.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
|
||||
#============================================================
|
||||
# CLOCK
|
||||
#============================================================
|
||||
set_location_assignment PIN_R8 -to CLOCK_50
|
||||
|
||||
#============================================================
|
||||
# LED
|
||||
#============================================================
|
||||
set_location_assignment PIN_A15 -to LED[0]
|
||||
set_location_assignment PIN_A13 -to LED[1]
|
||||
set_location_assignment PIN_B13 -to LED[2]
|
||||
set_location_assignment PIN_A11 -to LED[3]
|
||||
set_location_assignment PIN_D1 -to LED[4]
|
||||
set_location_assignment PIN_F3 -to LED[5]
|
||||
set_location_assignment PIN_B1 -to LED[6]
|
||||
set_location_assignment PIN_L3 -to LED[7]
|
||||
|
||||
#============================================================
|
||||
# KEY
|
||||
#============================================================
|
||||
set_location_assignment PIN_J15 -to KEY[0]
|
||||
set_location_assignment PIN_E1 -to KEY[1]
|
||||
|
||||
#============================================================
|
||||
# SW
|
||||
#============================================================
|
||||
set_location_assignment PIN_M1 -to SW[0]
|
||||
set_location_assignment PIN_T8 -to SW[1]
|
||||
set_location_assignment PIN_B9 -to SW[2]
|
||||
set_location_assignment PIN_M15 -to SW[3]
|
||||
|
||||
#============================================================
|
||||
# SDRAM
|
||||
#============================================================
|
||||
set_location_assignment PIN_M7 -to DRAM_BA[0]
|
||||
set_location_assignment PIN_M6 -to DRAM_BA[1]
|
||||
set_location_assignment PIN_R6 -to DRAM_DQM[0]
|
||||
set_location_assignment PIN_T5 -to DRAM_DQM[1]
|
||||
set_location_assignment PIN_L2 -to DRAM_RAS_N
|
||||
set_location_assignment PIN_L1 -to DRAM_CAS_N
|
||||
set_location_assignment PIN_L7 -to DRAM_CKE
|
||||
set_location_assignment PIN_R4 -to DRAM_CLK
|
||||
set_location_assignment PIN_C2 -to DRAM_WE_N
|
||||
set_location_assignment PIN_P6 -to DRAM_CS_N
|
||||
set_location_assignment PIN_G2 -to DRAM_DQ[0]
|
||||
set_location_assignment PIN_G1 -to DRAM_DQ[1]
|
||||
set_location_assignment PIN_L8 -to DRAM_DQ[2]
|
||||
set_location_assignment PIN_K5 -to DRAM_DQ[3]
|
||||
set_location_assignment PIN_K2 -to DRAM_DQ[4]
|
||||
set_location_assignment PIN_J2 -to DRAM_DQ[5]
|
||||
set_location_assignment PIN_J1 -to DRAM_DQ[6]
|
||||
set_location_assignment PIN_R7 -to DRAM_DQ[7]
|
||||
set_location_assignment PIN_T4 -to DRAM_DQ[8]
|
||||
set_location_assignment PIN_T2 -to DRAM_DQ[9]
|
||||
set_location_assignment PIN_T3 -to DRAM_DQ[10]
|
||||
set_location_assignment PIN_R3 -to DRAM_DQ[11]
|
||||
set_location_assignment PIN_R5 -to DRAM_DQ[12]
|
||||
set_location_assignment PIN_P3 -to DRAM_DQ[13]
|
||||
set_location_assignment PIN_N3 -to DRAM_DQ[14]
|
||||
set_location_assignment PIN_K1 -to DRAM_DQ[15]
|
||||
set_location_assignment PIN_P2 -to DRAM_ADDR[0]
|
||||
set_location_assignment PIN_N5 -to DRAM_ADDR[1]
|
||||
set_location_assignment PIN_N6 -to DRAM_ADDR[2]
|
||||
set_location_assignment PIN_M8 -to DRAM_ADDR[3]
|
||||
set_location_assignment PIN_P8 -to DRAM_ADDR[4]
|
||||
set_location_assignment PIN_T7 -to DRAM_ADDR[5]
|
||||
set_location_assignment PIN_N8 -to DRAM_ADDR[6]
|
||||
set_location_assignment PIN_T6 -to DRAM_ADDR[7]
|
||||
set_location_assignment PIN_R1 -to DRAM_ADDR[8]
|
||||
set_location_assignment PIN_P1 -to DRAM_ADDR[9]
|
||||
set_location_assignment PIN_N2 -to DRAM_ADDR[10]
|
||||
set_location_assignment PIN_N1 -to DRAM_ADDR[11]
|
||||
set_location_assignment PIN_L4 -to DRAM_ADDR[12]
|
||||
|
||||
#============================================================
|
||||
# Accelerometer and EEPROM
|
||||
#============================================================
|
||||
set_location_assignment PIN_F2 -to I2C_SCLK
|
||||
set_location_assignment PIN_F1 -to I2C_SDAT
|
||||
set_location_assignment PIN_G5 -to G_SENSOR_CS_N
|
||||
set_location_assignment PIN_M2 -to G_SENSOR_INT
|
||||
|
||||
#============================================================
|
||||
# ADC
|
||||
#============================================================
|
||||
set_location_assignment PIN_A10 -to ADC_CS_N
|
||||
set_location_assignment PIN_B10 -to ADC_SADDR
|
||||
set_location_assignment PIN_B14 -to ADC_SCLK
|
||||
set_location_assignment PIN_A9 -to ADC_SDAT
|
||||
|
||||
#============================================================
|
||||
# 2x13 GPIO Header
|
||||
#============================================================
|
||||
set_location_assignment PIN_A14 -to GPIO_2[0]
|
||||
set_location_assignment PIN_B16 -to GPIO_2[1]
|
||||
set_location_assignment PIN_C14 -to GPIO_2[2]
|
||||
set_location_assignment PIN_C16 -to GPIO_2[3]
|
||||
set_location_assignment PIN_C15 -to GPIO_2[4]
|
||||
set_location_assignment PIN_D16 -to GPIO_2[5]
|
||||
set_location_assignment PIN_D15 -to GPIO_2[6]
|
||||
set_location_assignment PIN_D14 -to GPIO_2[7]
|
||||
set_location_assignment PIN_F15 -to GPIO_2[8]
|
||||
set_location_assignment PIN_F16 -to GPIO_2[9]
|
||||
set_location_assignment PIN_F14 -to GPIO_2[10]
|
||||
set_location_assignment PIN_G16 -to GPIO_2[11]
|
||||
set_location_assignment PIN_G15 -to GPIO_2[12]
|
||||
set_location_assignment PIN_E15 -to GPIO_2_IN[0]
|
||||
set_location_assignment PIN_E16 -to GPIO_2_IN[1]
|
||||
set_location_assignment PIN_M16 -to GPIO_2_IN[2]
|
||||
|
||||
#============================================================
|
||||
# GPIO_0, GPIO_0 connect to GPIO Default
|
||||
#============================================================
|
||||
set_location_assignment PIN_A8 -to GPIO_0_IN[0]
|
||||
set_location_assignment PIN_D3 -to GPIO_0[0]
|
||||
set_location_assignment PIN_B8 -to GPIO_0_IN[1]
|
||||
set_location_assignment PIN_C3 -to GPIO_0[1]
|
||||
set_location_assignment PIN_A2 -to GPIO_0[2]
|
||||
set_location_assignment PIN_A3 -to GPIO_0[3]
|
||||
set_location_assignment PIN_B3 -to GPIO_0[4]
|
||||
set_location_assignment PIN_B4 -to GPIO_0[5]
|
||||
set_location_assignment PIN_A4 -to GPIO_0[6]
|
||||
set_location_assignment PIN_B5 -to GPIO_0[7]
|
||||
set_location_assignment PIN_A5 -to GPIO_0[8]
|
||||
set_location_assignment PIN_D5 -to GPIO_0[9]
|
||||
set_location_assignment PIN_B6 -to GPIO_0[10]
|
||||
set_location_assignment PIN_A6 -to GPIO_0[11]
|
||||
set_location_assignment PIN_B7 -to GPIO_0[12]
|
||||
set_location_assignment PIN_D6 -to GPIO_0[13]
|
||||
set_location_assignment PIN_A7 -to GPIO_0[14]
|
||||
set_location_assignment PIN_C6 -to GPIO_0[15]
|
||||
set_location_assignment PIN_C8 -to GPIO_0[16]
|
||||
set_location_assignment PIN_E6 -to GPIO_0[17]
|
||||
set_location_assignment PIN_E7 -to GPIO_0[18]
|
||||
set_location_assignment PIN_D8 -to GPIO_0[19]
|
||||
set_location_assignment PIN_E8 -to GPIO_0[20]
|
||||
set_location_assignment PIN_F8 -to GPIO_0[21]
|
||||
set_location_assignment PIN_F9 -to GPIO_0[22]
|
||||
set_location_assignment PIN_E9 -to GPIO_0[23]
|
||||
set_location_assignment PIN_C9 -to GPIO_0[24]
|
||||
set_location_assignment PIN_D9 -to GPIO_0[25]
|
||||
set_location_assignment PIN_E11 -to GPIO_0[26]
|
||||
set_location_assignment PIN_E10 -to GPIO_0[27]
|
||||
set_location_assignment PIN_C11 -to GPIO_0[28]
|
||||
set_location_assignment PIN_B11 -to GPIO_0[29]
|
||||
set_location_assignment PIN_A12 -to GPIO_0[30]
|
||||
set_location_assignment PIN_D11 -to GPIO_0[31]
|
||||
set_location_assignment PIN_D12 -to GPIO_0[32]
|
||||
set_location_assignment PIN_B12 -to GPIO_0[33]
|
||||
|
||||
#============================================================
|
||||
# GPIO_1, GPIO_1 connect to GPIO Default
|
||||
#============================================================
|
||||
set_location_assignment PIN_T9 -to GPIO_1_IN[0]
|
||||
set_location_assignment PIN_F13 -to GPIO_1[0]
|
||||
set_location_assignment PIN_R9 -to GPIO_1_IN[1]
|
||||
set_location_assignment PIN_T15 -to GPIO_1[1]
|
||||
set_location_assignment PIN_T14 -to GPIO_1[2]
|
||||
set_location_assignment PIN_T13 -to GPIO_1[3]
|
||||
set_location_assignment PIN_R13 -to GPIO_1[4]
|
||||
set_location_assignment PIN_T12 -to GPIO_1[5]
|
||||
set_location_assignment PIN_R12 -to GPIO_1[6]
|
||||
set_location_assignment PIN_T11 -to GPIO_1[7]
|
||||
set_location_assignment PIN_T10 -to GPIO_1[8]
|
||||
set_location_assignment PIN_R11 -to GPIO_1[9]
|
||||
set_location_assignment PIN_P11 -to GPIO_1[10]
|
||||
set_location_assignment PIN_R10 -to GPIO_1[11]
|
||||
set_location_assignment PIN_N12 -to GPIO_1[12]
|
||||
set_location_assignment PIN_P9 -to GPIO_1[13]
|
||||
set_location_assignment PIN_N9 -to GPIO_1[14]
|
||||
set_location_assignment PIN_N11 -to GPIO_1[15]
|
||||
set_location_assignment PIN_L16 -to GPIO_1[16]
|
||||
set_location_assignment PIN_K16 -to GPIO_1[17]
|
||||
set_location_assignment PIN_R16 -to GPIO_1[18]
|
||||
set_location_assignment PIN_L15 -to GPIO_1[19]
|
||||
set_location_assignment PIN_P15 -to GPIO_1[20]
|
||||
set_location_assignment PIN_P16 -to GPIO_1[21]
|
||||
set_location_assignment PIN_R14 -to GPIO_1[22]
|
||||
set_location_assignment PIN_N16 -to GPIO_1[23]
|
||||
set_location_assignment PIN_N15 -to GPIO_1[24]
|
||||
set_location_assignment PIN_P14 -to GPIO_1[25]
|
||||
set_location_assignment PIN_L14 -to GPIO_1[26]
|
||||
set_location_assignment PIN_N14 -to GPIO_1[27]
|
||||
set_location_assignment PIN_M10 -to GPIO_1[28]
|
||||
set_location_assignment PIN_L13 -to GPIO_1[29]
|
||||
set_location_assignment PIN_J16 -to GPIO_1[30]
|
||||
set_location_assignment PIN_K15 -to GPIO_1[31]
|
||||
set_location_assignment PIN_J13 -to GPIO_1[32]
|
||||
set_location_assignment PIN_J14 -to GPIO_1[33]
|
||||
|
||||
#============================================================
|
||||
# End of pin assignments by Terasic System Builder
|
||||
#============================================================
|
||||
|
||||
|
||||
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
|
||||
|
||||
set_global_assignment -name FAMILY "Cyclone IV E"
|
||||
set_global_assignment -name DEVICE EP4CE22F17C6
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY DE0_Nano_USTCRVSoC_top
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "10:11:55 FEBRUARY 10, 2019"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
|
||||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
|
||||
set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA
|
||||
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1
|
||||
set_global_assignment -name NOMINAL_CORE_SUPPLY_VOLTAGE 1.2V
|
||||
set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (SystemVerilog)"
|
||||
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT "SYSTEMVERILOG HDL" -section_id eda_simulation
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE DE0_Nano_USTCRVSoC_top.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/soc_top.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/soc_top_tb.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/core_top.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_regfile.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_id_stage.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_ex_branch_judge.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_bus_wrapper.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/core_alu.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/isp_uart.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/user_uart_tx.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/instr_rom.sv
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE ../../RTL/video_ram.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 STRATIX_DEVICE_IO_STANDARD "2.5 V"
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
@ -1,64 +0,0 @@
|
||||
module DE0_Nano_USTCRVSoC_top(
|
||||
//////////// CLOCK //////////
|
||||
input CLOCK_50,
|
||||
//////////// LED, KEY, Switch //////////
|
||||
output [7:0] LED,
|
||||
input [1:0] KEY,
|
||||
input [3:0] SW,
|
||||
//////////// 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,
|
||||
//////////// ADC //////////
|
||||
output ADC_CS_N, ADC_SADDR, ADC_SCLK,
|
||||
input ADC_SDAT,
|
||||
//////////// Accelerometer and EEPROM //////////
|
||||
output G_SENSOR_CS_N,
|
||||
input G_SENSOR_INT,
|
||||
output I2C_SCLK,
|
||||
inout I2C_SDAT,
|
||||
//////////// SDRAM //////////
|
||||
output [12:0] DRAM_ADDR,
|
||||
output [1:0] DRAM_BA,
|
||||
output DRAM_CAS_N, DRAM_CKE, DRAM_CLK, DRAM_CS_N, DRAM_RAS_N, DRAM_WE_N,
|
||||
inout [15:0] DRAM_DQ,
|
||||
output [1:0] DRAM_DQM
|
||||
);
|
||||
|
||||
logic rst_n;
|
||||
|
||||
soc_top soc_inst(
|
||||
.clk ( CLOCK_50 ),
|
||||
.rst_n ( rst_n ),
|
||||
.isp_uart_rx ( GPIO_1_IN[0] ),
|
||||
.isp_uart_tx ( GPIO_1[0] ),
|
||||
.user_uart_rx ( GPIO_1_IN[1] ),
|
||||
.user_uart_tx ( GPIO_1[1] ),
|
||||
.vga_hsync ( GPIO_0[33] ),
|
||||
.vga_vsync ( GPIO_0[32] ),
|
||||
.vga_pixel ( GPIO_0[31:16] )
|
||||
);
|
||||
|
||||
// 在开发板的LED上显示ISP-UART和USER-UART的发送灯和接收灯
|
||||
assign LED[7:4] = ~{GPIO_1_IN[0],GPIO_1[0],GPIO_1_IN[1],GPIO_1[1]};
|
||||
|
||||
// VGA GND
|
||||
assign GPIO_0[12] = 1'b0;
|
||||
|
||||
// 流水灯,指示SoC在运行
|
||||
reg [21:0] cnt = 22'h0;
|
||||
reg [ 3:0] flow = 4'h0;
|
||||
always @ (posedge CLOCK_50 or negedge rst_n)
|
||||
if(~rst_n) begin
|
||||
cnt <= 22'h0;
|
||||
flow <= 4'h0;
|
||||
end else begin
|
||||
cnt <= cnt + 22'h1;
|
||||
if(cnt==22'h0)
|
||||
flow <= {flow[2:0], ~flow[3]};
|
||||
end
|
||||
|
||||
assign LED[3:0] = flow;
|
||||
|
||||
endmodule
|
@ -1,13 +0,0 @@
|
||||
/* Quartus II 32-bit Version 13.1.0 Build 162 10/23/2013 SJ Full Version */
|
||||
JedecChain;
|
||||
FileRevision(JESD32A);
|
||||
DefaultMfr(6E);
|
||||
|
||||
P ActionCode(Cfg)
|
||||
Device PartName(EP4CE22) Path("E:/work-Lab/USTCRVSoC/Quartus/DE0_Nano/output_files/") File("DE0_Nano.jic") MfrSpec(OpMask(1) SEC_Device(EPCS64) Child_OpMask(1 1));
|
||||
|
||||
ChainEnd;
|
||||
|
||||
AlteraBegin;
|
||||
ChainType(JTAG);
|
||||
AlteraEnd;
|
Binary file not shown.
Binary file not shown.
@ -1,49 +0,0 @@
|
||||
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_immu,
|
||||
output logic [31:0] o_res
|
||||
);
|
||||
|
||||
logic [4:0] shamt_rs, shamt_imm;
|
||||
logic [31:0] shifted;
|
||||
logic signed [31:0] i_num1s, i_num2s, i_imms;
|
||||
|
||||
assign shamt_imm = i_immu[4:0];
|
||||
assign shamt_rs = i_num2u[4:0];
|
||||
assign i_num1s = i_num1u;
|
||||
assign i_num2s = i_num2u;
|
||||
assign i_imms = i_immu;
|
||||
|
||||
always_comb
|
||||
casex({i_funct7,i_funct3,i_opcode})
|
||||
// 算术类
|
||||
17'b0000000_000_0110011 : o_res <= i_num1u + i_num2u; // ADD
|
||||
17'bxxxxxxx_000_0010011 : o_res <= i_num1u + i_immu ; // ADDI
|
||||
17'b0100000_000_0110011 : o_res <= i_num1u - i_num2u; // SUB
|
||||
// LUI类
|
||||
17'bxxxxxxx_xxx_0110111 : o_res <= i_immu; // LUI
|
||||
// 逻辑类
|
||||
17'b0000000_100_0110011 : o_res <= i_num1u ^ i_num2u; // XOR
|
||||
17'bxxxxxxx_100_0010011 : o_res <= i_num1u ^ i_immu ; // XORI
|
||||
17'b0000000_110_0110011 : o_res <= i_num1u | i_num2u; // OR
|
||||
17'bxxxxxxx_110_0010011 : o_res <= i_num1u | i_immu ; // ORI
|
||||
17'b0000000_111_0110011 : o_res <= i_num1u & i_num2u; // AND
|
||||
17'bxxxxxxx_111_0010011 : o_res <= i_num1u & i_immu ; // ANDI
|
||||
// 位移类
|
||||
17'b0000000_001_0110011 : o_res <= i_num1u << shamt_rs ; // SLL
|
||||
17'b0000000_001_0010011 : o_res <= i_num1u << shamt_imm; // SLLI
|
||||
17'b0000000_101_0110011 : o_res <= i_num1u >> shamt_rs ; // SRL
|
||||
17'b0000000_101_0010011 : o_res <= i_num1u >> shamt_imm; // SRL
|
||||
17'b0100000_101_0110011 : o_res <= i_num1s >> shamt_rs ; // SRA
|
||||
17'b0100000_101_0010011 : o_res <= i_num1s >> shamt_imm; // SRAI
|
||||
// 比较类
|
||||
17'b0000000_010_0110011 : o_res <= (i_num1s < i_num2s) ? 1 : 0; // SLT
|
||||
17'bxxxxxxx_010_0010011 : o_res <= (i_num1s < i_imms ) ? 1 : 0; // SLTI
|
||||
17'b0000000_011_0110011 : o_res <= (i_num1u < i_num2u) ? 1 : 0; // SLTU
|
||||
17'bxxxxxxx_011_0010011 : o_res <= (i_num1u < i_immu ) ? 1 : 0; // SLTIU
|
||||
// 无操作
|
||||
default : o_res <= 0;
|
||||
endcase
|
||||
|
||||
endmodule
|
@ -1,109 +0,0 @@
|
||||
module core_bus_wrapper(
|
||||
input logic clk, rst_n,
|
||||
input logic i_re, i_we,
|
||||
output logic o_conflict, o_conflict_latch,
|
||||
input logic [ 2:0] i_funct3,
|
||||
input logic [31:0] i_addr,
|
||||
input logic [31:0] i_wdata,
|
||||
output logic [31:0] o_rdata,
|
||||
|
||||
naive_bus.master bus_master
|
||||
);
|
||||
|
||||
logic i_re_latch;
|
||||
logic [1:0] addr_lsb, rd_addr_lsb;
|
||||
logic [31:0] addr_bus, wdata, rdata, rdata_latch;
|
||||
logic [2:0] rd_funct3;
|
||||
logic [3:0] byte_enable;
|
||||
|
||||
assign addr_bus = {i_addr[31:2], 2'b0};
|
||||
assign addr_lsb = i_addr[1:0];
|
||||
|
||||
assign o_conflict = (bus_master.rd_req & ~bus_master.rd_gnt) | (bus_master.wr_req & ~bus_master.wr_gnt);
|
||||
|
||||
assign bus_master.rd_req = i_re;
|
||||
assign bus_master.rd_be = i_re ? byte_enable : 4'h0;
|
||||
assign bus_master.rd_addr = i_re ? addr_bus : 0;
|
||||
assign rdata = bus_master.rd_data;
|
||||
|
||||
assign bus_master.wr_req = i_we;
|
||||
assign bus_master.wr_be = i_we ? byte_enable : 4'h0;
|
||||
assign bus_master.wr_addr = i_we ? addr_bus : 0;
|
||||
assign bus_master.wr_data = i_we ? wdata : 0;
|
||||
|
||||
|
||||
always_comb
|
||||
casex(i_funct3)
|
||||
3'bx00 : if (addr_lsb==2'b00) byte_enable <= 4'b0001;
|
||||
else if(addr_lsb==2'b01) byte_enable <= 4'b0010;
|
||||
else if(addr_lsb==2'b10) byte_enable <= 4'b0100;
|
||||
else byte_enable <= 4'b1000;
|
||||
3'bx01 : if (addr_lsb==2'b00) byte_enable <= 4'b0011;
|
||||
else if(addr_lsb==2'b10) byte_enable <= 4'b1100;
|
||||
else byte_enable <= 4'b0000;
|
||||
3'b010 : if (addr_lsb==2'b00) byte_enable <= 4'b1111;
|
||||
else byte_enable <= 4'b0000;
|
||||
default : byte_enable <= 4'b0000;
|
||||
endcase
|
||||
|
||||
|
||||
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'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;
|
||||
3'b010 : if (addr_lsb==2'b00) wdata <= i_wdata;
|
||||
else wdata <= 0;
|
||||
default : wdata <= 0;
|
||||
endcase
|
||||
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n) begin
|
||||
i_re_latch <= 1'b0;
|
||||
rd_addr_lsb <= 2'b0;
|
||||
rd_funct3 <= 3'b0;
|
||||
o_conflict_latch <= 1'b0;
|
||||
rdata_latch <= 0;
|
||||
end else begin
|
||||
i_re_latch <= i_re;
|
||||
rd_addr_lsb <= addr_lsb;
|
||||
rd_funct3 <= i_funct3;
|
||||
o_conflict_latch <= o_conflict;
|
||||
rdata_latch <= o_rdata;
|
||||
end
|
||||
|
||||
// assign o_rdata
|
||||
always_comb
|
||||
if(i_re_latch) begin
|
||||
if(~o_conflict_latch)
|
||||
case(rd_funct3)
|
||||
3'b000 : if (rd_addr_lsb==2'b00) o_rdata <= {{24{rdata[ 7]}}, rdata[ 7: 0]};
|
||||
else if(rd_addr_lsb==2'b01) o_rdata <= {{24{rdata[15]}}, rdata[15: 8]};
|
||||
else if(rd_addr_lsb==2'b10) o_rdata <= {{24{rdata[23]}}, rdata[23:16]};
|
||||
else o_rdata <= {{24{rdata[31]}}, rdata[31:24]};
|
||||
3'b100 : if (rd_addr_lsb==2'b00) o_rdata <= { 24'b0, rdata[ 7: 0]};
|
||||
else if(rd_addr_lsb==2'b01) o_rdata <= { 24'b0, rdata[15: 8]};
|
||||
else if(rd_addr_lsb==2'b10) o_rdata <= { 24'b0, rdata[23:16]};
|
||||
else o_rdata <= { 24'b0, rdata[31:24]};
|
||||
3'b001 : if (rd_addr_lsb==2'b00) o_rdata <= {{16{rdata[15]}}, rdata[15: 0]};
|
||||
else if(rd_addr_lsb==2'b10) o_rdata <= {{16{rdata[31]}}, rdata[31:16]};
|
||||
else o_rdata <= 0;
|
||||
3'b101 : if (rd_addr_lsb==2'b00) o_rdata <= { 16'b0, rdata[15: 0]};
|
||||
else if(rd_addr_lsb==2'b10) o_rdata <= { 16'b0, rdata[31:16]};
|
||||
else o_rdata <= 0;
|
||||
3'b010 : if (rd_addr_lsb==2'b00) o_rdata <= rdata;
|
||||
else o_rdata <= 0;
|
||||
default : o_rdata <= 0;
|
||||
endcase
|
||||
else
|
||||
o_rdata <= 0;
|
||||
end else begin
|
||||
o_rdata <= rdata_latch;
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,26 +0,0 @@
|
||||
module core_ex_branch_judge(
|
||||
input logic i_branch,
|
||||
input logic [31:0] i_num1u, i_num2u,
|
||||
input logic [ 2:0] i_funct3,
|
||||
output logic o_branch
|
||||
);
|
||||
|
||||
logic branch_judge_res;
|
||||
assign o_branch = i_branch & branch_judge_res;
|
||||
|
||||
logic signed [31:0] i_num1s, i_num2s;
|
||||
assign i_num1s = i_num1u;
|
||||
assign i_num2s = i_num2u;
|
||||
|
||||
always_comb
|
||||
case(i_funct3)
|
||||
3'b000 : branch_judge_res <= (i_num1u == i_num2u); // BEQ
|
||||
3'b001 : branch_judge_res <= (i_num1u != i_num2u); // BNE
|
||||
3'b100 : branch_judge_res <= (i_num1s < i_num2s); // BLT
|
||||
3'b101 : branch_judge_res <= (i_num1s >= i_num2s); // BGE
|
||||
3'b110 : branch_judge_res <= (i_num1u < i_num2u); // BLTU
|
||||
3'b111 : branch_judge_res <= (i_num1u >= i_num2u); // BGEU
|
||||
default: branch_judge_res <= 1'b0;
|
||||
endcase
|
||||
|
||||
endmodule
|
@ -1,79 +0,0 @@
|
||||
module core_id_stage(
|
||||
input logic [31:0] i_instr,
|
||||
input logic [31:0] i_pc,
|
||||
output logic [ 4:0] o_rs1_addr, o_rs2_addr,
|
||||
output logic o_rs1_en, o_rs2_en,
|
||||
output logic o_jal, o_jalr, o_branch_may,
|
||||
output logic o_nextpc2reg, o_alures2reg, o_memory2reg,
|
||||
output logic o_mem_write,
|
||||
output logic [31:0] o_pc_plus_imm, o_imm,
|
||||
output logic [4:0] o_dst_reg_addr,
|
||||
output logic [6:0] o_opcode, o_funct7,
|
||||
output logic [2:0] o_funct3,
|
||||
output logic [31:0] o_next_pc
|
||||
);
|
||||
|
||||
logic [31:0] instr;
|
||||
|
||||
enum {UKNOWN_TYPE, R_TYPE, I_TYPE, IZ_TYPE, S_TYPE, B_TYPE, U_TYPE, J_TYPE} instr_type;
|
||||
|
||||
localparam OPCODE_JAL = 7'b1101111, // rd=pc+4, pc= pc+imm*2,
|
||||
OPCODE_JALR = 7'b1100111, // rd=pc+4, pc= rs1+imm
|
||||
OPCODE_BXXX = 7'b1100011, // conditional branch, pc= pc+imm*2,
|
||||
OPCODE_LUI = 7'b0110111, // rd = 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
|
||||
|
||||
assign instr = i_instr;
|
||||
assign o_next_pc = i_pc + 4;
|
||||
assign o_pc_plus_imm = i_pc + o_imm;
|
||||
assign {o_funct7, o_rs2_addr, o_rs1_addr, o_funct3, o_dst_reg_addr, o_opcode} = instr;
|
||||
|
||||
assign o_jal = (o_opcode == OPCODE_JAL );
|
||||
assign o_jalr = (o_opcode == OPCODE_JALR );
|
||||
assign o_branch_may = (o_opcode == OPCODE_BXXX );
|
||||
assign o_nextpc2reg = (o_opcode == OPCODE_JAL || o_opcode == OPCODE_JALR );
|
||||
assign o_alures2reg = (o_opcode == OPCODE_LUI || o_opcode == OPCODE_ALI || o_opcode == OPCODE_ALR);
|
||||
assign o_memory2reg = (o_opcode == OPCODE_LOAD );
|
||||
assign o_mem_write = (o_opcode == OPCODE_STORE);
|
||||
|
||||
// calculate instruction type
|
||||
always_comb
|
||||
case(o_opcode)
|
||||
OPCODE_JAL : instr_type <= J_TYPE;
|
||||
OPCODE_JALR : instr_type <= I_TYPE;
|
||||
OPCODE_BXXX : instr_type <= B_TYPE;
|
||||
OPCODE_LUI : instr_type <= U_TYPE;
|
||||
OPCODE_ALI : instr_type <= (o_funct3==3'b011) ? IZ_TYPE : I_TYPE;
|
||||
OPCODE_ALR : instr_type <= R_TYPE;
|
||||
OPCODE_LOAD : instr_type <= I_TYPE;
|
||||
OPCODE_STORE: instr_type <= S_TYPE;
|
||||
default : instr_type <= UKNOWN_TYPE;
|
||||
endcase
|
||||
|
||||
always_comb
|
||||
case(instr_type)
|
||||
I_TYPE : o_imm <= {{20{instr[31]}} , instr[31:20]};
|
||||
IZ_TYPE: o_imm <= { 20'h0 , instr[31:20]};
|
||||
S_TYPE : o_imm <= {{20{instr[31]}} , instr[31:25], instr[11:7]};
|
||||
B_TYPE : o_imm <= {{20{instr[31]}} , instr[7], instr[30:25], instr[11:8], 1'b0};
|
||||
U_TYPE : o_imm <= { instr[31:12] , 12'h0 };
|
||||
J_TYPE : o_imm <= {{12{instr[31]}} , instr[19:12], instr[20], instr[30:21], 1'b0};
|
||||
default: o_imm <= 0;
|
||||
endcase
|
||||
|
||||
always_comb
|
||||
case(instr_type)
|
||||
R_TYPE : {o_rs2_en, o_rs1_en} <= 2'b11;
|
||||
I_TYPE : {o_rs2_en, o_rs1_en} <= 2'b01;
|
||||
IZ_TYPE: {o_rs2_en, o_rs1_en} <= 2'b01;
|
||||
S_TYPE : {o_rs2_en, o_rs1_en} <= 2'b11;
|
||||
B_TYPE : {o_rs2_en, o_rs1_en} <= 2'b11;
|
||||
U_TYPE : {o_rs2_en, o_rs1_en} <= 2'b00;
|
||||
J_TYPE : {o_rs2_en, o_rs1_en} <= 2'b00;
|
||||
default: {o_rs2_en, o_rs1_en} <= 2'b00;
|
||||
endcase
|
||||
|
||||
endmodule
|
@ -1,84 +0,0 @@
|
||||
// Priority : Write Port 1 > Write Port 2 > Write Port 3
|
||||
module core_regfile(
|
||||
input logic clk, rst_n,
|
||||
input logic rd_latch,
|
||||
// Read port 1
|
||||
input logic i_re1,
|
||||
input logic [4:0] i_raddr1,
|
||||
output logic [31:0] o_rdata1,
|
||||
// Read port 2
|
||||
input logic i_re2,
|
||||
input logic [4:0] i_raddr2,
|
||||
output logic [31:0] o_rdata2,
|
||||
// Write port 1
|
||||
input logic i_we1,
|
||||
input logic [4:0] i_waddr1,
|
||||
input logic [31:0] i_wdata1,
|
||||
// Write port 2
|
||||
input logic i_we2,
|
||||
input logic [4:0] i_waddr2,
|
||||
input logic [31:0] i_wdata2,
|
||||
// Write port 3
|
||||
input logic i_we3,
|
||||
input logic [4:0] i_waddr3,
|
||||
input logic [31:0] i_wdata3
|
||||
);
|
||||
|
||||
logic [31:1] [31:0] reg_file_cell = 992'h0;
|
||||
|
||||
// handle regwrite
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if(~rst_n)
|
||||
reg_file_cell <= 992'h0;
|
||||
else begin
|
||||
if(i_we3 && i_waddr3!=5'h0 && ~(i_we1 && i_waddr1==i_waddr3) && ~(i_we2 && i_waddr2==i_waddr3) )
|
||||
reg_file_cell[i_waddr3] <= i_wdata3;
|
||||
if(i_we2 && i_waddr2!=5'h0 && ~(i_we1 && i_waddr1==i_waddr2) )
|
||||
reg_file_cell[i_waddr2] <= i_wdata2;
|
||||
if(i_we1 && i_waddr1!=5'h0 )
|
||||
reg_file_cell[i_waddr1] <= i_wdata1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if(~rst_n)
|
||||
o_rdata1 <= 0;
|
||||
else begin
|
||||
if(rd_latch) begin
|
||||
o_rdata1 <= o_rdata1;
|
||||
end else if(i_re1 && i_raddr1!=5'h0) begin
|
||||
if (i_we1 && i_raddr1==i_waddr1)
|
||||
o_rdata1 <= i_wdata1;
|
||||
else if(i_we2 && i_raddr1==i_waddr2)
|
||||
o_rdata1 <= i_wdata2;
|
||||
else if(i_we3 && i_raddr1==i_waddr3)
|
||||
o_rdata1 <= i_wdata3;
|
||||
else
|
||||
o_rdata1 <= reg_file_cell[i_raddr1];
|
||||
end else
|
||||
o_rdata1 <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge clk or negedge rst_n) begin
|
||||
if(~rst_n)
|
||||
o_rdata2 <= 0;
|
||||
else begin
|
||||
if(rd_latch) begin
|
||||
o_rdata2 <= o_rdata2;
|
||||
end else if(i_re2 && i_raddr2!=5'h0) begin
|
||||
if (i_we1 && i_raddr2==i_waddr1)
|
||||
o_rdata2 <= i_wdata1;
|
||||
else if(i_we2 && i_raddr2==i_waddr2)
|
||||
o_rdata2 <= i_wdata2;
|
||||
else if(i_we3 && i_raddr2==i_waddr3)
|
||||
o_rdata2 <= i_wdata3;
|
||||
else
|
||||
o_rdata2 <= reg_file_cell[i_raddr2];
|
||||
end else
|
||||
o_rdata2 <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
257
RTL/core_top.sv
257
RTL/core_top.sv
@ -1,257 +0,0 @@
|
||||
module core_top(
|
||||
input logic clk, rst_n,
|
||||
input logic [31:0] i_boot_addr,
|
||||
naive_bus.master instr_master, data_master
|
||||
);
|
||||
|
||||
// IF stage out
|
||||
logic [31:0] if_pc;
|
||||
|
||||
// ID stage
|
||||
logic [31:0] id_instr, id_pc;
|
||||
logic id_rs1_en, id_rs2_en;
|
||||
logic [4:0] id_rs1_addr, id_rs2_addr, id_dst_reg_addr;
|
||||
logic [31:0] id_next_pc;
|
||||
logic id_jal, id_jalr, id_branch_may;
|
||||
logic id_nextpc2reg, id_alures2reg, id_memory2reg;
|
||||
logic id_memwrite;
|
||||
logic [6:0] id_opcode, id_funct7;
|
||||
logic [2:0] id_funct3;
|
||||
logic [31:0] id_pc_plus_imm, id_imm;
|
||||
|
||||
// EX stage
|
||||
logic ex_jalr, ex_branch_may, ex_branch;
|
||||
logic ex_nextpc2reg, ex_alures2reg, ex_memory2reg;
|
||||
logic ex_memwrite;
|
||||
logic [31:0] ex_s1, ex_s2;
|
||||
logic [6:0] ex_opcode, ex_funct7;
|
||||
logic [2:0] ex_funct3;
|
||||
logic [31:0] ex_imm, ex_alu_res;
|
||||
logic [4:0] ex_dst_reg_addr;
|
||||
logic [31:0] ex_s1_plus_imm, ex_next_pc, ex_pc_plus_imm;
|
||||
|
||||
// MEM stage
|
||||
logic [2:0] mem_funct3;
|
||||
logic mem_memory2reg, mem_alures2reg, mem_memwrite;
|
||||
logic [31:0] mem_alu_res, mem_mem_wdata, mem_s1_plus_imm;
|
||||
logic [4:0] mem_dst_reg_addr;
|
||||
|
||||
// WB stage
|
||||
logic wb_memory2reg;
|
||||
logic [31:0] wb_reg_wdata;
|
||||
logic [4:0] wb_dst_reg_addr;
|
||||
|
||||
// write regfile conflict signal
|
||||
logic launch_nop, pc_stall, id_stall, ex_stall, mem_stall, wreg_conflict;
|
||||
logic id_data_bus_conflict, mem_data_bus_conflict;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// conflict - comb logic
|
||||
// -------------------------------------------------------------------------------
|
||||
assign pc_stall = id_stall | id_data_bus_conflict;
|
||||
assign id_stall = wreg_conflict | mem_data_bus_conflict;
|
||||
assign ex_stall = mem_data_bus_conflict;
|
||||
assign mem_stall = mem_data_bus_conflict;
|
||||
assign launch_nop = ex_branch | ex_jalr | wreg_conflict;
|
||||
|
||||
assign wreg_conflict =
|
||||
(id_rs1_en & ex_alures2reg & (id_rs1_addr== ex_dst_reg_addr) ) |
|
||||
(id_rs2_en & ex_alures2reg & (id_rs2_addr== ex_dst_reg_addr) ) |
|
||||
(id_rs1_en & ex_memory2reg & (id_rs1_addr== ex_dst_reg_addr) ) |
|
||||
(id_rs2_en & ex_memory2reg & (id_rs2_addr== ex_dst_reg_addr) ) |
|
||||
(id_rs1_en &mem_memory2reg & (id_rs1_addr==mem_dst_reg_addr) ) |
|
||||
(id_rs2_en &mem_memory2reg & (id_rs2_addr==mem_dst_reg_addr) ) ;
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// IF stage - comb logic
|
||||
// -------------------------------------------------------------------------------
|
||||
always_comb
|
||||
if(ex_branch)
|
||||
if_pc <= ex_pc_plus_imm;
|
||||
else if(ex_jalr)
|
||||
if_pc <= ex_s1_plus_imm;
|
||||
else if(id_jal)
|
||||
if_pc <= id_pc_plus_imm;
|
||||
else if(pc_stall)
|
||||
if_pc <= id_pc;
|
||||
else
|
||||
if_pc <= id_next_pc;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// IF-ID stage - timing logic
|
||||
// -------------------------------------------------------------------------------
|
||||
core_bus_wrapper inst_bus_wrap_inst(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_re ( ~id_stall ),
|
||||
.i_we ( 1'b0 ),
|
||||
.o_conflict_latch ( id_data_bus_conflict ),
|
||||
.i_funct3 ( 3'b010 ),
|
||||
.i_addr ( if_pc ),
|
||||
.i_wdata ( 0 ),
|
||||
.o_rdata ( id_instr ),
|
||||
.bus_master ( instr_master )
|
||||
);
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n)
|
||||
id_pc <= {i_boot_addr[31:2],2'b00} - 4;
|
||||
else
|
||||
id_pc <= if_pc;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// ID stage - comb logic
|
||||
// -------------------------------------------------------------------------------
|
||||
core_id_stage core_id_stage_inst(
|
||||
.i_instr ( id_instr ),
|
||||
.i_pc ( id_pc ),
|
||||
.o_rs1_addr ( id_rs1_addr ),
|
||||
.o_rs2_addr ( id_rs2_addr ),
|
||||
.o_rs1_en ( id_rs1_en ),
|
||||
.o_rs2_en ( id_rs2_en ),
|
||||
.o_jal ( id_jal ),
|
||||
.o_jalr ( id_jalr ),
|
||||
.o_branch_may ( id_branch_may ),
|
||||
.o_nextpc2reg ( id_nextpc2reg ),
|
||||
.o_alures2reg ( id_alures2reg ),
|
||||
.o_memory2reg ( id_memory2reg ),
|
||||
.o_mem_write ( id_memwrite ),
|
||||
.o_pc_plus_imm ( id_pc_plus_imm ),
|
||||
.o_imm ( id_imm ),
|
||||
.o_dst_reg_addr ( id_dst_reg_addr),
|
||||
.o_opcode ( id_opcode ),
|
||||
.o_funct7 ( id_funct7 ),
|
||||
.o_funct3 ( id_funct3 ),
|
||||
.o_next_pc ( id_next_pc )
|
||||
);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// ID-EX stage - timing logic
|
||||
// -------------------------------------------------------------------------------
|
||||
core_regfile core_regfile_inst(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.rd_latch ( ex_stall ),
|
||||
.i_re1 ( id_rs1_en ),
|
||||
.i_raddr1 ( id_rs1_addr ),
|
||||
.o_rdata1 ( ex_s1 ),
|
||||
.i_re2 ( id_rs2_en ),
|
||||
.i_raddr2 ( id_rs2_addr ),
|
||||
.o_rdata2 ( ex_s2 ),
|
||||
.i_we1 ( ex_nextpc2reg ),
|
||||
.i_waddr1 ( ex_dst_reg_addr),
|
||||
.i_wdata1 ( ex_next_pc ),
|
||||
.i_we2 ( mem_alures2reg ),
|
||||
.i_waddr2 (mem_dst_reg_addr),
|
||||
.i_wdata2 ( mem_alu_res ),
|
||||
.i_we3 ( wb_memory2reg ),
|
||||
.i_waddr3 ( wb_dst_reg_addr),
|
||||
.i_wdata3 ( wb_reg_wdata )
|
||||
);
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n) begin
|
||||
ex_jalr <= 1'b0;
|
||||
ex_branch_may <= 1'b0;
|
||||
ex_nextpc2reg <= 1'b0;
|
||||
ex_alures2reg <= 1'b0;
|
||||
ex_memory2reg <= 1'b0;
|
||||
ex_memwrite <= 1'b0;
|
||||
ex_dst_reg_addr <= 5'h0;
|
||||
ex_imm <= 0;
|
||||
ex_opcode <= 7'h0;
|
||||
ex_funct3 <= 3'h0;
|
||||
ex_funct7 <= 7'h0;
|
||||
ex_next_pc <= 0;
|
||||
end else if(~ex_stall) begin
|
||||
ex_jalr <= launch_nop ? 1'b0 : id_jalr;
|
||||
ex_branch_may <= launch_nop ? 1'b0 : id_branch_may;
|
||||
ex_pc_plus_imm <= id_pc_plus_imm;
|
||||
ex_nextpc2reg <= launch_nop ? 1'b0 : id_nextpc2reg;
|
||||
ex_alures2reg <= launch_nop ? 1'b0 : id_alures2reg;
|
||||
ex_memory2reg <= launch_nop ? 1'b0 : id_memory2reg;
|
||||
ex_memwrite <= launch_nop ? 1'b0 : id_memwrite;
|
||||
ex_dst_reg_addr <= id_dst_reg_addr;
|
||||
ex_imm <= id_imm;
|
||||
ex_opcode <= id_opcode;
|
||||
ex_funct3 <= id_funct3;
|
||||
ex_funct7 <= id_funct7;
|
||||
ex_next_pc <= id_next_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_s1 ),
|
||||
.i_num2u ( ex_s2 ),
|
||||
.i_immu ( ex_imm ),
|
||||
.o_res ( ex_alu_res )
|
||||
);
|
||||
core_ex_branch_judge core_ex_branch_judge_inst(
|
||||
.i_branch ( ex_branch_may ),
|
||||
.i_num1u ( ex_s1 ),
|
||||
.i_num2u ( ex_s2 ),
|
||||
.i_funct3 ( ex_funct3 ),
|
||||
.o_branch ( ex_branch )
|
||||
);
|
||||
assign ex_s1_plus_imm = ex_s1 + ex_imm;
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// 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_wdata <= 0;
|
||||
mem_s1_plus_imm <= 0;
|
||||
mem_funct3 <= 3'b0;
|
||||
end else if(~mem_stall) begin
|
||||
mem_memory2reg <= ex_memory2reg;
|
||||
mem_alures2reg <= ex_alures2reg;
|
||||
mem_alu_res <= ex_alu_res;
|
||||
mem_dst_reg_addr<= ex_dst_reg_addr;
|
||||
mem_memwrite <= ex_memwrite;
|
||||
mem_mem_wdata <= ex_s2;
|
||||
mem_s1_plus_imm <= ex_s1_plus_imm;
|
||||
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_s1_plus_imm ),
|
||||
.i_wdata ( mem_mem_wdata ),
|
||||
.o_rdata ( wb_reg_wdata ),
|
||||
.bus_master ( data_master )
|
||||
);
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n) begin
|
||||
wb_memory2reg <= 1'b0;
|
||||
wb_dst_reg_addr <= 5'h0;
|
||||
end else begin
|
||||
wb_memory2reg <= mem_memory2reg;
|
||||
wb_dst_reg_addr <= mem_dst_reg_addr;
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,61 +0,0 @@
|
||||
module instr_rom(
|
||||
input logic clk, rst_n,
|
||||
naive_bus.slave bus
|
||||
);
|
||||
localparam INSTR_CNT = 30'd36;
|
||||
wire [0:INSTR_CNT-1] [31:0] instr_rom_cell = {
|
||||
32'h12300013, // 0x00008000
|
||||
32'h45600013, // 0x00008004
|
||||
32'h00010137, // 0x00008008
|
||||
32'h40016113, // 0x0000800c
|
||||
32'h00704293, // 0x00008010
|
||||
32'h008000ef, // 0x00008014
|
||||
32'h05c0006f, // 0x00008018
|
||||
32'h00306513, // 0x0000801c
|
||||
32'h00a2f663, // 0x00008020
|
||||
32'h0002e313, // 0x00008024
|
||||
32'h00008067, // 0x00008028
|
||||
32'hffc10113, // 0x0000802c
|
||||
32'h00112023, // 0x00008030
|
||||
32'hfff28293, // 0x00008034
|
||||
32'hffc10113, // 0x00008038
|
||||
32'h00512023, // 0x0000803c
|
||||
32'hfddff0ef, // 0x00008040
|
||||
32'h00012283, // 0x00008044
|
||||
32'h00410113, // 0x00008048
|
||||
32'hfff28293, // 0x0000804c
|
||||
32'hffc10113, // 0x00008050
|
||||
32'h00612023, // 0x00008054
|
||||
32'hfc5ff0ef, // 0x00008058
|
||||
32'h00012383, // 0x0000805c
|
||||
32'h00410113, // 0x00008060
|
||||
32'h00730333, // 0x00008064
|
||||
32'h00012083, // 0x00008068
|
||||
32'h00410113, // 0x0000806c
|
||||
32'h00008067, // 0x00008070
|
||||
32'h000062b3, // 0x00008074
|
||||
32'h000302b7, // 0x00008078
|
||||
32'h00628023, // 0x0000807c
|
||||
32'h00c003b7, // 0x00008080
|
||||
32'hfff38393, // 0x00008084
|
||||
32'hfe039ee3, // 0x00008088
|
||||
32'hfe9ff06f, // 0x0000808c
|
||||
};
|
||||
|
||||
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
|
||||
|
222
RTL/isp_uart.sv
222
RTL/isp_uart.sv
@ -1,222 +0,0 @@
|
||||
// 一个能作为naive bus 主设备的调试模块
|
||||
// 它接收用户从UART发来的命令,操控复位等信号,或对总线进行读写。用户可以使用UART命令复位整个SoC,上传程序,或者查看运行时的RAM数据。
|
||||
|
||||
// 命令列表(全部命令为ASCII,人类可读, 每个命令使用\r或\n或\r\n或\n\r结尾):
|
||||
// 1、复位命令
|
||||
// 发送: r\n
|
||||
// 效果: 将o_rst_n信号拉低若干个时钟周期
|
||||
// 返回: rst done\n
|
||||
// 2、指定boot地址的复位命令
|
||||
// 2. w\n : o_run = 1 , return running \n
|
||||
// 3. s\n : o_run = 0 , return stoped \n
|
||||
// 4. addr=data\n : write [addr] = data , example: 00000100 928cd0f1\n , return : 00000100=928cd0f1 , note:automaticly align address to 4byte
|
||||
// 5. addr\n : read [addr] , example: 00000100\n return : 928cd0f1
|
||||
//
|
||||
|
||||
module isp_uart #(
|
||||
parameter UART_RX_CLK_DIV = 108, // 50MHz/4/115200Hz=108
|
||||
parameter UART_TX_CLK_DIV = 434 // 50MHz/1/115200Hz=434
|
||||
)(
|
||||
input logic clk,
|
||||
input logic i_uart_rx,
|
||||
output logic o_uart_tx,
|
||||
output logic o_rst_n,
|
||||
output logic [31:0] o_boot_addr,
|
||||
naive_bus.master bus
|
||||
);
|
||||
|
||||
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_binary;
|
||||
logic [ 3:0] rx_binary_l;
|
||||
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, GETBOOTADDR, SETBOOTADDR, ADDR, EQUAL, DATA, FINAL, TRASH} fsm = NEW;
|
||||
|
||||
`define C (rx_data=="r")
|
||||
`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" ) )
|
||||
|
||||
initial o_boot_addr = 0;
|
||||
assign o_rst_n = &rst_chain;
|
||||
|
||||
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];
|
||||
|
||||
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
|
||||
|
||||
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 )
|
||||
);
|
||||
|
||||
uart_tx_line #(
|
||||
.UART_TX_CLK_DIV (UART_TX_CLK_DIV)
|
||||
) uart_tx_line_inst (
|
||||
.clk ( clk ),
|
||||
.o_tx ( o_uart_tx ),
|
||||
.i_start ( tx_start ),
|
||||
.i_data ( tx_data )
|
||||
);
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
for(i=0; i<8; i++) begin : convert_binary_to_ascii
|
||||
always_comb
|
||||
if(bus.rd_data[3+4*i:4*i]>4'h9)
|
||||
rd_data_ascii[i] = "a" - 8'd10 + bus.rd_data[3+4*i:4*i];
|
||||
else
|
||||
rd_data_ascii[i] = "0" + bus.rd_data[3+4*i:4*i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @ (posedge clk)
|
||||
rd_ok <= (bus.rd_req & bus.rd_gnt);
|
||||
|
||||
always @ (posedge clk)
|
||||
wr_ok <= (bus.wr_req & bus.wr_gnt);
|
||||
|
||||
always @ (posedge clk)
|
||||
if (rd_ok) begin
|
||||
tx_start<= 1'b1;
|
||||
tx_data <= rd_data_ascii;
|
||||
end else if(wr_ok) begin
|
||||
tx_start<= 1'b1;
|
||||
tx_data <= "wr done ";
|
||||
end else if(rx_ready && `E) begin
|
||||
if(fsm==CMD) begin
|
||||
tx_start<= 1'b1;
|
||||
tx_data <= "rst done";
|
||||
end else if(fsm==TRASH) begin
|
||||
tx_start<= 1'b1;
|
||||
tx_data <= "invalid ";
|
||||
end
|
||||
end else begin
|
||||
tx_start<= 1'b0;
|
||||
tx_data <= 64'h0;
|
||||
end
|
||||
|
||||
always @ (posedge clk)
|
||||
if(rx_ready && fsm==CMD && `E)
|
||||
rst_chain <= 4'h0;
|
||||
else
|
||||
rst_chain <= {rst_chain[2:0],1'b1};
|
||||
|
||||
always @ (posedge clk)
|
||||
if (bus.rd_req) begin
|
||||
if(bus.rd_gnt)
|
||||
bus.rd_req <= 1'b0;
|
||||
end else if(bus.wr_req) begin
|
||||
if(bus.wr_gnt)
|
||||
bus.wr_req <= 1'b0;
|
||||
end else if( rx_ready ) begin
|
||||
case(fsm)
|
||||
NEW : if (`C) begin
|
||||
fsm <= CMD;
|
||||
wr_data <= 0;
|
||||
end else if(`S || `E) begin
|
||||
fsm <= NEW;
|
||||
addr <= 0;
|
||||
wr_data <= 0;
|
||||
end else if(`N) begin
|
||||
fsm <= ADDR;
|
||||
addr <= {addr[27:0], rx_binary_l}; // get a addr
|
||||
end else begin
|
||||
fsm <= TRASH;
|
||||
end
|
||||
CMD : if (`E) begin
|
||||
o_boot_addr <= {wr_data[31:2],2'b00}; // 设置复位的boot地址,后两位截断(双字对齐)
|
||||
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地址,
|
||||
wr_data <= {wr_data[27:0], rx_binary_l}; // get a data
|
||||
end else begin
|
||||
fsm <= TRASH;
|
||||
end
|
||||
ADDR : if (`E) begin
|
||||
fsm <= NEW; // get a read command
|
||||
bus.rd_req <= 1'b1; // TODO : launch a bus read
|
||||
bus.rd_addr <= addr;
|
||||
addr <= 0;
|
||||
wr_data <= 0;
|
||||
end else if(`N) begin
|
||||
fsm <= ADDR;
|
||||
addr <= {addr[27:0], rx_binary_l}; // get a addr
|
||||
end else if(`S) begin
|
||||
fsm <= EQUAL; // get addr down, waiting for data, maybe a write command
|
||||
end else begin
|
||||
fsm <= TRASH;
|
||||
end
|
||||
EQUAL : if (`E) begin
|
||||
fsm <= NEW; // get a read command
|
||||
bus.rd_req <= 1'b1; // TODO : launch a bus read
|
||||
bus.rd_addr <= addr;
|
||||
addr <= 0;
|
||||
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
|
||||
end else if(`S) begin
|
||||
fsm <= EQUAL;
|
||||
end else begin
|
||||
fsm <= TRASH;
|
||||
end
|
||||
DATA : if (`E) begin
|
||||
fsm <= NEW; // get a write command
|
||||
bus.wr_req <= 1'b1; // TODO : launch a bus write
|
||||
bus.wr_addr <= addr;
|
||||
bus.wr_data <= wr_data;
|
||||
addr <= 0;
|
||||
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
|
||||
end else if(`S) begin
|
||||
fsm <= FINAL; // get data down, waiting for \r or \n
|
||||
end else begin
|
||||
fsm <= TRASH;
|
||||
end
|
||||
FINAL : if (`E) begin
|
||||
fsm <= NEW; // get a write command
|
||||
bus.wr_req <= 1'b1; // TODO : launch a bus write
|
||||
bus.wr_addr <= addr;
|
||||
bus.wr_data <= wr_data;
|
||||
addr <= 0;
|
||||
wr_data <= 0;
|
||||
end else if(`S) begin
|
||||
fsm <= FINAL; // get addr down, waiting for \r or \n
|
||||
end else begin
|
||||
fsm <= TRASH;
|
||||
end
|
||||
default : if (`E) begin
|
||||
// get a syntax error
|
||||
fsm <= NEW;
|
||||
addr <= 0;
|
||||
wr_data <= 0;
|
||||
end else begin
|
||||
fsm <= TRASH;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,30 +0,0 @@
|
||||
`ifndef NAIVE_BUS_SV
|
||||
`define NAIVE_BUS_SV
|
||||
|
||||
interface naive_bus();
|
||||
// read interface
|
||||
logic rd_req, rd_gnt;
|
||||
logic [3:0] rd_be;
|
||||
logic [31:0] rd_addr, rd_data;
|
||||
// write interface
|
||||
logic wr_req, wr_gnt;
|
||||
logic [3:0] wr_be;
|
||||
logic [31:0] wr_addr, wr_data;
|
||||
|
||||
modport master(
|
||||
output rd_req, rd_be, rd_addr,
|
||||
input rd_data, rd_gnt,
|
||||
output wr_req, wr_be, wr_addr, wr_data,
|
||||
input wr_gnt
|
||||
);
|
||||
|
||||
modport slave(
|
||||
input rd_req, rd_be, rd_addr,
|
||||
output rd_data, rd_gnt,
|
||||
input wr_req, wr_be, wr_addr, wr_data,
|
||||
output wr_gnt
|
||||
);
|
||||
|
||||
endinterface
|
||||
|
||||
`endif
|
@ -1,118 +0,0 @@
|
||||
module naive_bus_router #(
|
||||
parameter [7:0] N_MASTER = 2,
|
||||
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,
|
||||
naive_bus.slave masters [N_MASTER-1:0] ,
|
||||
naive_bus.master slaves [ N_SLAVE-1:0]
|
||||
);
|
||||
|
||||
`define SLAVE_ADDRESS(master_addr, slave_index) (master_addr) & ( SLAVES_MASK[slave_index] )
|
||||
`define SLAVE_INRANGE(master_addr, slave_index) ( ((master_addr) & (~SLAVES_MASK[slave_index]))==(SLAVES_BASE[slave_index]) )
|
||||
|
||||
logic [N_MASTER-1:0] masters_rd_req;
|
||||
logic [N_MASTER-1:0][ 3:0] masters_rd_be;
|
||||
logic [N_MASTER-1:0][31:0] masters_rd_addr;
|
||||
logic [N_MASTER-1:0] masters_wr_req;
|
||||
logic [N_MASTER-1:0][ 3:0] masters_wr_be;
|
||||
logic [N_MASTER-1:0][31:0] masters_wr_addr;
|
||||
logic [N_MASTER-1:0][31:0] masters_wr_data;
|
||||
logic [N_MASTER-1:0] masters_rd_gnt = 1'b0;
|
||||
logic [N_MASTER-1:0][ 7:0] master_rd_slv_index = {N_MASTER{N_SLAVE}};
|
||||
logic [N_MASTER-1:0][ 7:0] master_rd_slv_index_latch = {N_MASTER{N_SLAVE}};
|
||||
logic [N_MASTER-1:0][ 7:0] slv = {N_MASTER{N_SLAVE}};
|
||||
|
||||
logic [N_SLAVE-1:0] slaves_wr_gnt, slaves_rd_gnt;
|
||||
logic [N_SLAVE-1:0][ 7:0] mst = {N_SLAVE{N_MASTER}};
|
||||
logic [N_SLAVE-1:0][ 7:0] slaves_wr_mst_index = {N_SLAVE{N_MASTER}};
|
||||
logic [N_SLAVE-1:0][ 7:0] slaves_rd_mst_index = {N_SLAVE{N_MASTER}};
|
||||
logic [N_SLAVE :0][31:0] slaves_rd_data;
|
||||
|
||||
|
||||
assign slaves_rd_data[N_SLAVE] = 0;
|
||||
|
||||
generate
|
||||
genvar slv_i_assign;
|
||||
for(slv_i_assign=0; slv_i_assign<N_SLAVE; slv_i_assign++) begin: assign_slaves
|
||||
assign slaves_wr_gnt[slv_i_assign] = slaves[slv_i_assign].wr_gnt;
|
||||
assign slaves_rd_gnt[slv_i_assign] = slaves[slv_i_assign].rd_gnt;
|
||||
assign slaves_rd_data[slv_i_assign]= slaves[slv_i_assign].rd_data;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
genvar mst_i_assign;
|
||||
for(mst_i_assign=0; mst_i_assign<N_MASTER; mst_i_assign++) begin: assign_masters
|
||||
assign masters_rd_req [mst_i_assign] = masters[mst_i_assign].rd_req;
|
||||
assign masters_rd_be [mst_i_assign] = masters[mst_i_assign].rd_be;
|
||||
assign masters_rd_addr[mst_i_assign] = masters[mst_i_assign].rd_addr;
|
||||
assign masters_wr_req [mst_i_assign] = masters[mst_i_assign].wr_req;
|
||||
assign masters_wr_be [mst_i_assign] = masters[mst_i_assign].wr_be;
|
||||
assign masters_wr_addr[mst_i_assign] = masters[mst_i_assign].wr_addr;
|
||||
assign masters_wr_data[mst_i_assign] = masters[mst_i_assign].wr_data;
|
||||
assign masters[mst_i_assign].rd_gnt = masters_rd_gnt[mst_i_assign];
|
||||
assign masters[mst_i_assign].rd_data = slaves_rd_data[master_rd_slv_index_latch[mst_i_assign]];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
genvar slv_i;
|
||||
for(slv_i=0; slv_i<N_SLAVE; slv_i++) begin: generate_slave_loop
|
||||
always_comb begin
|
||||
slaves[slv_i].rd_req = 1'b0;
|
||||
slaves[slv_i].rd_be = 4'h0;
|
||||
slaves[slv_i].rd_addr = 0;
|
||||
slaves_rd_mst_index[slv_i] = N_MASTER;
|
||||
slaves[slv_i].wr_req = 1'b0;
|
||||
slaves[slv_i].wr_be = 4'h0;
|
||||
slaves[slv_i].wr_addr = 0;
|
||||
slaves[slv_i].wr_data = 0;
|
||||
slaves_wr_mst_index[slv_i] = N_MASTER;
|
||||
for(mst[slv_i]=0; mst[slv_i]<N_MASTER; mst[slv_i]+=1) begin
|
||||
if( `SLAVE_INRANGE(masters_rd_addr[mst[slv_i]], slv_i) & masters_rd_req[mst[slv_i]] ) begin
|
||||
slaves[slv_i].rd_req = 1'b1;
|
||||
slaves[slv_i].rd_be = masters_rd_be[mst[slv_i]];
|
||||
slaves[slv_i].rd_addr = `SLAVE_ADDRESS(masters_rd_addr[mst[slv_i]], slv_i);
|
||||
slaves_rd_mst_index[slv_i] = mst[slv_i];
|
||||
end
|
||||
if( `SLAVE_INRANGE(masters_wr_addr[mst[slv_i]], slv_i) & masters_wr_req[mst[slv_i]] ) begin
|
||||
slaves[slv_i].wr_req = 1'b1;
|
||||
slaves[slv_i].wr_be = masters_wr_be[mst[slv_i]];
|
||||
slaves[slv_i].wr_addr = `SLAVE_ADDRESS(masters_wr_addr[mst[slv_i]], slv_i);
|
||||
slaves[slv_i].wr_data = masters_wr_data[mst[slv_i]];
|
||||
slaves_wr_mst_index[slv_i] = mst[slv_i];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
generate
|
||||
genvar mst_i;
|
||||
for(mst_i=0; mst_i<N_MASTER; mst_i++) begin: generate_master_loop
|
||||
always_comb begin
|
||||
masters[mst_i].wr_gnt = 1'b1;
|
||||
masters_rd_gnt[mst_i] = 1'b1;
|
||||
master_rd_slv_index[mst_i] = N_SLAVE;
|
||||
for(slv[mst_i]=0; slv[mst_i]<N_SLAVE; slv[mst_i]+=1) begin
|
||||
if( `SLAVE_INRANGE(masters_rd_addr[mst_i], slv[mst_i]) ) begin
|
||||
masters_rd_gnt[mst_i] = (slaves_rd_mst_index[slv[mst_i]]==mst_i) ? slaves_rd_gnt[slv[mst_i]] : 1'b0;
|
||||
master_rd_slv_index[mst_i] = masters_rd_gnt[mst_i] ? slv[mst_i] : N_SLAVE;
|
||||
end
|
||||
if( `SLAVE_INRANGE(masters_wr_addr[mst_i], slv[mst_i]) ) begin
|
||||
masters[mst_i].wr_gnt = (slaves_wr_mst_index[slv[mst_i]]==mst_i) ? slaves_wr_gnt[slv[mst_i]] : 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n)
|
||||
master_rd_slv_index_latch <= {N_MASTER{N_SLAVE}};
|
||||
else
|
||||
master_rd_slv_index_latch <= master_rd_slv_index;
|
||||
|
||||
endmodule
|
30
RTL/ram.sv
30
RTL/ram.sv
@ -1,30 +0,0 @@
|
||||
module ram( // 1024B
|
||||
input logic clk, rst_n,
|
||||
input logic i_we,
|
||||
input logic [ 9:0] i_waddr, i_raddr, i_raddr2,
|
||||
input logic [ 7:0] i_wdata,
|
||||
output logic [ 7:0] o_rdata, o_rdata2
|
||||
);
|
||||
|
||||
initial begin o_rdata = 8'h0; o_rdata2 = 8'h0; end
|
||||
|
||||
localparam SIZE = 1024;
|
||||
logic [SIZE-1:0] [7:0] data_ram_cell;
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n)
|
||||
o_rdata <= 0;
|
||||
else
|
||||
o_rdata <= data_ram_cell[i_raddr];
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n)
|
||||
o_rdata2 <= 0;
|
||||
else
|
||||
o_rdata2 <= data_ram_cell[i_raddr2];
|
||||
|
||||
always @ (posedge clk)
|
||||
if(i_we)
|
||||
data_ram_cell[i_waddr] <= i_wdata;
|
||||
|
||||
endmodule
|
@ -1,51 +0,0 @@
|
||||
module ram_bus_wrapper( // 4kB, valid address: 0x0000_0000 ~ 0x0000_0fff
|
||||
input logic clk, rst_n,
|
||||
naive_bus.slave bus
|
||||
);
|
||||
|
||||
logic [9:0] cell_rd_addr, cell_wr_addr;
|
||||
|
||||
assign cell_rd_addr = bus.rd_addr[11:2];
|
||||
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(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_we ( bus.wr_req & bus.wr_be[0] ),
|
||||
.i_waddr ( cell_wr_addr ),
|
||||
.i_raddr ( cell_rd_addr ),
|
||||
.i_wdata ( bus.wr_data[ 7: 0] ),
|
||||
.o_rdata ( bus.rd_data[ 7: 0] )
|
||||
);
|
||||
ram ram_block_inst_1(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_we ( bus.wr_req & bus.wr_be[1] ),
|
||||
.i_waddr ( cell_wr_addr ),
|
||||
.i_raddr ( cell_rd_addr ),
|
||||
.i_wdata ( bus.wr_data[15: 8] ),
|
||||
.o_rdata ( bus.rd_data[15: 8] )
|
||||
);
|
||||
ram ram_block_inst_2(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_we ( bus.wr_req & bus.wr_be[2] ),
|
||||
.i_waddr ( cell_wr_addr ),
|
||||
.i_raddr ( cell_rd_addr ),
|
||||
.i_wdata ( bus.wr_data[23:16] ),
|
||||
.o_rdata ( bus.rd_data[23:16] )
|
||||
);
|
||||
ram ram_block_inst_3(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_we ( bus.wr_req & bus.wr_be[3] ),
|
||||
.i_waddr ( cell_wr_addr ),
|
||||
.i_raddr ( cell_rd_addr ),
|
||||
.i_wdata ( bus.wr_data[31:24] ),
|
||||
.o_rdata ( bus.rd_data[31:24] )
|
||||
);
|
||||
|
||||
endmodule
|
109
RTL/soc_top.sv
109
RTL/soc_top.sv
@ -1,109 +0,0 @@
|
||||
module soc_top (
|
||||
// 时钟,要求50MHz
|
||||
input logic clk,
|
||||
// 复位信号输出
|
||||
output logic rst_n,
|
||||
// 调试器UART信号
|
||||
input logic isp_uart_rx,
|
||||
output logic isp_uart_tx,
|
||||
// 用户UART信号
|
||||
input logic user_uart_rx,
|
||||
output logic user_uart_tx,
|
||||
// VGA显示输出信号
|
||||
output logic vga_hsync, vga_vsync,
|
||||
output logic [15:0] vga_pixel
|
||||
);
|
||||
logic [31:0] boot_addr;
|
||||
|
||||
naive_bus bus_masters[3]();
|
||||
naive_bus bus_slaves[5]();
|
||||
|
||||
// 一个能作为naive bus 主设备的调试器
|
||||
// 它接收用户从UART发来的命令,操控复位等信号,或对总线进行读写。用户可以使用UART命令复位整个SoC,上传程序,或者查看运行时的RAM数据。
|
||||
isp_uart 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] )
|
||||
);
|
||||
|
||||
// RV32I 核
|
||||
core_top core_top_inst(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_boot_addr ( boot_addr ),
|
||||
.instr_master ( bus_masters[1] ),
|
||||
.data_master ( bus_masters[2] )
|
||||
);
|
||||
|
||||
// 指令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 video_ram_inst(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.bus ( bus_slaves[3] ),
|
||||
.o_vsync ( vga_vsync ),
|
||||
.o_hsync ( vga_hsync ),
|
||||
.o_pixel ( vga_pixel )
|
||||
);
|
||||
|
||||
|
||||
// 用户UART
|
||||
user_uart_tx user_uart_tx_inst(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.o_uart_tx ( user_uart_tx ),
|
||||
.bus ( bus_slaves[4] )
|
||||
);
|
||||
|
||||
|
||||
// 3主5从总线仲裁器
|
||||
//
|
||||
// 主(越靠前优先级越高):
|
||||
// 0. UART调试器
|
||||
// 1. Core Instr Master
|
||||
// 2. Core Data Master
|
||||
//
|
||||
// 从:
|
||||
// 1. 指令ROM, 地址空间 00000000~00000fff
|
||||
// 2. 指令RAM, 地址空间 00008000~00008fff
|
||||
// 3. 数据RAM, 地址空间 00010000~00010fff
|
||||
// 4. 显存RAM, 地址空间 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
|
||||
|
@ -1,21 +0,0 @@
|
||||
module soc_top_tb();
|
||||
|
||||
logic clk, rst_n;
|
||||
initial clk = 1'b1;
|
||||
always #1 clk = ~clk;
|
||||
|
||||
wire vga_vsync, vga_hsync, user_uart_tx, isp_uart_tx;
|
||||
wire [15:0] vga_pixel;
|
||||
|
||||
soc_top soc_inst(
|
||||
.clk ( clk ),
|
||||
.isp_uart_rx ( 1'b1 ),
|
||||
.isp_uart_tx ( isp_uart_tx ),
|
||||
.user_uart_rx ( 1'b1 ),
|
||||
.user_uart_tx ( user_uart_tx),
|
||||
.vga_hsync ( vga_hsync ),
|
||||
.vga_vsync ( vga_vsync ),
|
||||
.vga_pixel ( vga_pixel )
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,53 +0,0 @@
|
||||
module uart_rx #(
|
||||
parameter UART_RX_CLK_DIV = 108 // 50MHz/4/115200Hz=108
|
||||
)(
|
||||
input logic clk,
|
||||
input logic i_rx,
|
||||
output logic o_ready,
|
||||
output logic [7:0] o_data
|
||||
);
|
||||
|
||||
logic rx_bit, busy, last_busy=1'b0;
|
||||
logic [ 5:0] shift = 6'h0, status = 6'h0;
|
||||
logic [ 7:0] databuf = 8'h0;
|
||||
logic [31:0] cnt = 0;
|
||||
|
||||
initial o_ready = 1'b0;
|
||||
initial o_data = 8'h0;
|
||||
|
||||
assign busy = (status!=6'h0);
|
||||
assign rx_bit = (shift[0]&shift[1]) | (shift[0]&i_rx) | (shift[1]&i_rx);
|
||||
|
||||
always @ (posedge clk)
|
||||
last_busy <= busy;
|
||||
|
||||
always @ (posedge clk)
|
||||
o_ready <= (~busy & last_busy);
|
||||
|
||||
always @ (posedge clk)
|
||||
cnt <= (cnt<UART_RX_CLK_DIV-1) ? cnt+1 : 0;
|
||||
|
||||
always @ (posedge clk)
|
||||
if(cnt==0) begin
|
||||
if(~busy) begin
|
||||
if(shift == 6'b111000)
|
||||
status <= 6'h1;
|
||||
end else begin
|
||||
if(status[5] == 1'b0) begin
|
||||
if(status[1:0] == 2'b11)
|
||||
databuf <= {rx_bit, databuf[7:1]};
|
||||
status <= status + 6'h1;
|
||||
end else begin
|
||||
if(status<62) begin
|
||||
status <= 6'd62;
|
||||
o_data <= databuf;
|
||||
end else begin
|
||||
status <= status + 6'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
shift <= shift<<1;
|
||||
shift[0] <= i_rx;
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,47 +0,0 @@
|
||||
|
||||
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,
|
||||
input logic [7:0][7:0] i_data
|
||||
);
|
||||
|
||||
logic [31:0] cnt = 0;
|
||||
logic [ 6:0] tx_cnt = 0;
|
||||
logic [90:0] tx_buffer, tx_shift;
|
||||
initial tx_shift = 91'h0;
|
||||
initial o_tx = 1'b1;
|
||||
|
||||
assign tx_buffer = {2'b11, 8'h0A , // 0x0A = \n , a end of line
|
||||
2'b01, i_data[0],
|
||||
2'b01, i_data[1],
|
||||
2'b01, i_data[2],
|
||||
2'b01, i_data[3],
|
||||
2'b01, i_data[4],
|
||||
2'b01, i_data[5],
|
||||
2'b01, i_data[6],
|
||||
2'b01, i_data[7],
|
||||
1'b0};
|
||||
|
||||
always @ (posedge clk)
|
||||
cnt <= (cnt<UART_TX_CLK_DIV-1) ? cnt+1 : 0;
|
||||
|
||||
always @ (posedge clk)
|
||||
if(tx_cnt>7'd0) begin
|
||||
if(cnt==0) begin
|
||||
{tx_shift, o_tx} <= {1'b1, tx_shift};
|
||||
tx_cnt <= tx_cnt - 7'd1;
|
||||
end
|
||||
end else begin
|
||||
o_tx <= 1'b1;
|
||||
if(i_start) begin
|
||||
tx_cnt <= 7'd93;
|
||||
tx_shift <= tx_buffer;
|
||||
end else begin
|
||||
tx_cnt <= 7'd0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -1,99 +0,0 @@
|
||||
|
||||
module user_uart_tx #(
|
||||
parameter UART_TX_CLK_DIV = 434 // 50MHz/1/115200Hz=434
|
||||
)(
|
||||
input logic clk, rst_n,
|
||||
output logic o_uart_tx,
|
||||
naive_bus.slave bus
|
||||
);
|
||||
localparam TX_CNT = 5'd19;
|
||||
|
||||
logic [ 7:0] fifo_rd_pointer=8'h0, fifo_wr_pointer=8'h0, fifo_len;
|
||||
logic fifo_full, fifo_empty;
|
||||
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;
|
||||
|
||||
initial o_uart_tx = 1'b1;
|
||||
|
||||
assign rd_addr_valid = (bus.rd_addr[31:2] == 30'h0);
|
||||
assign wr_addr_valid = (bus.wr_addr[31:2] == 30'h0);
|
||||
|
||||
assign fifo_len = fifo_wr_pointer - fifo_rd_pointer;
|
||||
assign fifo_empty = (fifo_len==8'h00);
|
||||
assign fifo_full = (fifo_len==8'hff);
|
||||
|
||||
assign bus.rd_gnt = bus.rd_req;
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n)
|
||||
bus.rd_data <= 0;
|
||||
else begin
|
||||
if(bus.rd_req & rd_addr_valid)
|
||||
bus.rd_data <= {24'h0, fifo_len};
|
||||
else
|
||||
bus.rd_data <= 0;
|
||||
end
|
||||
|
||||
always_comb
|
||||
if(bus.wr_req) begin
|
||||
if(wr_addr_valid && bus.wr_be[0]) begin
|
||||
bus.wr_gnt <= ~fifo_full;
|
||||
end else begin
|
||||
bus.wr_gnt <= 1'b1;
|
||||
end
|
||||
end else begin
|
||||
bus.wr_gnt <= 1'b0;
|
||||
end
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n) begin
|
||||
fifo_wr_pointer <= 8'h0;
|
||||
end else begin
|
||||
if(bus.wr_req & wr_addr_valid & bus.wr_be[0] & ~fifo_full) begin
|
||||
fifo_wr_pointer <= fifo_wr_pointer + 8'h1;
|
||||
end
|
||||
end
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n)
|
||||
cnt <= 0;
|
||||
else
|
||||
cnt <= (cnt<UART_TX_CLK_DIV-1) ? cnt+1 : 0;
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n) begin
|
||||
fifo_rd_pointer <= 8'h0;
|
||||
o_uart_tx <= 1'b1;
|
||||
tx_shift <= 8'hff;
|
||||
tx_cnt <= 5'h0;
|
||||
end else begin
|
||||
if(tx_cnt>5'd0) begin
|
||||
if(cnt==0) begin
|
||||
if(tx_cnt==TX_CNT) begin
|
||||
{tx_shift, o_uart_tx} <= {fifo_rd_data, 1'b0};
|
||||
fifo_rd_pointer <= fifo_rd_pointer + 8'h1;
|
||||
end else begin
|
||||
{tx_shift, o_uart_tx} <= {1'b1, tx_shift};
|
||||
end
|
||||
tx_cnt <= tx_cnt - 5'd1;
|
||||
end
|
||||
end else begin
|
||||
o_uart_tx <= 1'b1;
|
||||
tx_cnt <= fifo_empty ? 5'd0 : TX_CNT;
|
||||
end
|
||||
end
|
||||
|
||||
ram ram_for_uart_tx_fifo_inst(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_we ( bus.wr_req & wr_addr_valid & bus.wr_be[0] & ~fifo_full ),
|
||||
.i_waddr ( {2'h0,fifo_wr_pointer} ),
|
||||
.i_wdata ( bus.wr_data[7:0] ),
|
||||
.i_raddr ( {2'h0,fifo_rd_pointer} ),
|
||||
.o_rdata ( fifo_rd_data )
|
||||
);
|
||||
|
||||
endmodule
|
335
RTL/video_ram.sv
335
RTL/video_ram.sv
@ -1,335 +0,0 @@
|
||||
module video_ram(
|
||||
input logic clk, rst_n,
|
||||
output logic o_hsync, o_vsync,
|
||||
output logic [15:0] o_pixel,
|
||||
naive_bus.slave bus
|
||||
);
|
||||
|
||||
logic [ 9:0] vga_addr_h;
|
||||
logic [ 1:0] vga_addr_l, vga_addr_l_latch = 2'b00;
|
||||
logic [ 7:0] vga_ascii;
|
||||
logic [ 9:0] cell_rd_addr, cell_wr_addr;
|
||||
logic [ 7:0] vga_rdata [4];
|
||||
|
||||
assign cell_rd_addr = bus.rd_addr[11:2];
|
||||
assign cell_wr_addr = bus.wr_addr[11:2];
|
||||
|
||||
assign bus.rd_gnt = bus.rd_req;
|
||||
assign bus.wr_gnt = bus.wr_req;
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n)
|
||||
vga_addr_l_latch <= 2'b00;
|
||||
else
|
||||
vga_addr_l_latch <= vga_addr_l;
|
||||
|
||||
ram ram_block_inst_0(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_we ( bus.wr_req & bus.wr_be[0] ),
|
||||
.i_waddr ( cell_wr_addr ),
|
||||
.i_raddr ( cell_rd_addr ),
|
||||
.i_wdata ( bus.wr_data[ 7: 0] ),
|
||||
.o_rdata ( bus.rd_data[ 7: 0] ),
|
||||
.i_raddr2 ( vga_addr_h ),
|
||||
.o_rdata2 ( vga_rdata[0] )
|
||||
);
|
||||
ram ram_block_inst_1(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_we ( bus.wr_req & bus.wr_be[1] ),
|
||||
.i_waddr ( cell_wr_addr ),
|
||||
.i_raddr ( cell_rd_addr ),
|
||||
.i_wdata ( bus.wr_data[15: 8] ),
|
||||
.o_rdata ( bus.rd_data[15: 8] ),
|
||||
.i_raddr2 ( vga_addr_h ),
|
||||
.o_rdata2 ( vga_rdata[1] )
|
||||
);
|
||||
ram ram_block_inst_2(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_we ( bus.wr_req & bus.wr_be[2] ),
|
||||
.i_waddr ( cell_wr_addr ),
|
||||
.i_raddr ( cell_rd_addr ),
|
||||
.i_wdata ( bus.wr_data[23:16] ),
|
||||
.o_rdata ( bus.rd_data[23:16] ),
|
||||
.i_raddr2 ( vga_addr_h ),
|
||||
.o_rdata2 ( vga_rdata[2] )
|
||||
);
|
||||
ram ram_block_inst_3(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.i_we ( bus.wr_req & bus.wr_be[3] ),
|
||||
.i_waddr ( cell_wr_addr ),
|
||||
.i_raddr ( cell_rd_addr ),
|
||||
.i_wdata ( bus.wr_data[31:24] ),
|
||||
.o_rdata ( bus.rd_data[31:24] ),
|
||||
.i_raddr2 ( vga_addr_h ),
|
||||
.o_rdata2 ( vga_rdata[3] )
|
||||
);
|
||||
|
||||
always_comb
|
||||
case(vga_addr_l_latch)
|
||||
2'b00 : vga_ascii <= vga_rdata[0];
|
||||
2'b01 : vga_ascii <= vga_rdata[1];
|
||||
2'b10 : vga_ascii <= vga_rdata[2];
|
||||
2'b11 : vga_ascii <= vga_rdata[3];
|
||||
endcase
|
||||
|
||||
vgaChar98x36 vga_char_inst(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.hsync ( o_hsync ),
|
||||
.vsync ( o_vsync ),
|
||||
.pixel ( o_pixel ),
|
||||
.addr ( {vga_addr_h,vga_addr_l} ),
|
||||
.ascii ( vga_ascii )
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
module vgaChar98x36(
|
||||
// clock
|
||||
input clk, rst_n,
|
||||
// vga interfaces
|
||||
output hsync, vsync,
|
||||
output [15:0] pixel,
|
||||
// user interface
|
||||
output req,
|
||||
output [11:0] addr,
|
||||
input [7:0] ascii
|
||||
);
|
||||
wire b;
|
||||
wire [15:0] req_pixel;
|
||||
reg [15:0] border, border_latch;
|
||||
|
||||
wire [2:0] x_l;
|
||||
wire [3:0] y_l;
|
||||
wire [6:0] x_h;
|
||||
wire [5:0] y_h;
|
||||
wire [9:0] x, y;
|
||||
reg [9:0] x_latch, y_latch;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
x_latch <= x;
|
||||
y_latch <= y;
|
||||
border_latch <= border;
|
||||
end
|
||||
|
||||
assign {x_h, x_l} = x - 10'd8;
|
||||
assign {y_h, y_l} = y - 10'd12;
|
||||
|
||||
assign addr = y_h * 12'd98 + x_h;
|
||||
|
||||
vga vga_inst(
|
||||
.clk (clk),
|
||||
.hsync (hsync),
|
||||
.vsync (vsync),
|
||||
.pixel (pixel),
|
||||
.req (req),
|
||||
.x (x),
|
||||
.y (y),
|
||||
.req_pixel (req_pixel)
|
||||
);
|
||||
|
||||
assign req_pixel = ( x_latch>=8 && x_latch<(800-8) && y_latch>=12 && y_latch<(600-12) ) ? {16{b}} : border_latch;
|
||||
|
||||
always @ (posedge clk)
|
||||
if(req)
|
||||
border <= ( x<5 || x>(800-5) || y<5 || y>(600-5) ) ? 16'hff00 : 16'h0000;
|
||||
|
||||
char8x16_rom char_8x16_rom_inst(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.ascii ( ascii ),
|
||||
.x ( x_l ),
|
||||
.y ( y_l ),
|
||||
.b ( b )
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
module vga(
|
||||
// clock
|
||||
input clk,
|
||||
// vga interface
|
||||
output reg hsync, vsync,
|
||||
output reg [15:0] pixel,
|
||||
// user interface
|
||||
output req,
|
||||
output [ 9:0] x, y,
|
||||
input [15:0] req_pixel
|
||||
);
|
||||
localparam H_END = 800,
|
||||
H_SYNCSTART = H_END + 8,
|
||||
H_SYNCEND = H_SYNCSTART + 128,
|
||||
H_PERIOD = H_SYNCEND + 72,
|
||||
|
||||
V_END = 600,
|
||||
V_SYNCSTART = V_END + 8,
|
||||
V_SYNCEND = V_SYNCSTART + 4,
|
||||
V_PERIOD = V_SYNCEND + 36;
|
||||
|
||||
reg [31:0] hcnt,vcnt;
|
||||
|
||||
always @ (posedge clk)
|
||||
hcnt <= (hcnt<H_PERIOD) ? hcnt + 1 : 0;
|
||||
|
||||
always @ (posedge clk)
|
||||
hsync <= ~(hcnt>=H_SYNCSTART && hcnt<H_SYNCEND);
|
||||
|
||||
always @ (posedge hsync)
|
||||
vcnt <= (vcnt<V_PERIOD) ? vcnt + 1 : 0;
|
||||
|
||||
always @ (posedge hsync)
|
||||
vsync <= ~(vcnt>=V_SYNCSTART && vcnt<V_SYNCEND);
|
||||
|
||||
wire h_range = hcnt<H_END;
|
||||
wire v_range = vcnt<V_END;
|
||||
wire range = (h_range & v_range);
|
||||
|
||||
assign x = range ? hcnt[9:0] : 10'h0;
|
||||
assign y = range ? vcnt[9:0] : 10'h0;
|
||||
|
||||
assign req = range;
|
||||
|
||||
always @ (posedge clk)
|
||||
pixel <= (hcnt>0 && hcnt<=H_END && v_range) ? req_pixel : 16'h0;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 存放所有ASCII字符的字码
|
||||
// 该ROM自动综合成Block RAM
|
||||
module char8x16_rom(
|
||||
input clk, rst_n,
|
||||
input [7:0] ascii,
|
||||
input [2:0] x,
|
||||
input [3:0] y,
|
||||
output b
|
||||
);
|
||||
reg [ 6:0] addr = 7'h0;
|
||||
reg [127:0] char = 128'h0;
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n)
|
||||
addr <= 7'h0;
|
||||
else
|
||||
addr <= ~{y,x};
|
||||
|
||||
assign b = char[addr];
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if(~rst_n)
|
||||
char <= 128'h0;
|
||||
else
|
||||
case(ascii)
|
||||
33: char <= 128'h00000018181818181808000818000000; //!0
|
||||
34: char <= 128'h00000034242424000000000000000000; //"1
|
||||
35: char <= 128'h0000000016247F2424247E2424000000; //#2
|
||||
36: char <= 128'h000000083E6848681C1612127C101000; //$3
|
||||
37: char <= 128'h00000061D296740810162949C6000000; //%4
|
||||
38: char <= 128'h000000003C646438724ACE467F000000; //&5
|
||||
39: char <= 128'h00000018181818000000000000000000; //'6
|
||||
40: char <= 128'h00000004081810303030301010180C04; //(7
|
||||
41: char <= 128'h000000201008080C0404040C08181020; //)8
|
||||
42: char <= 128'h000000080A341C6A0800000000000000; //*9
|
||||
43: char <= 128'h0000000000001818187F181818000000; //+10
|
||||
44: char <= 128'h00000000000000000000001818083000; //,11
|
||||
45: char <= 128'h0000000000000000003C000000000000; //-12
|
||||
46: char <= 128'h00000000000000000000001818000000; //.13
|
||||
47: char <= 128'h0000000206040C080810102020400000; ///14
|
||||
48: char <= 128'h000000003C6642475B7342663C000000; //015
|
||||
49: char <= 128'h0000000018784808080808087E000000; //116
|
||||
50: char <= 128'h000000003C460606040810207E000000; //217
|
||||
51: char <= 128'h000000007C0606043C0202067C000000; //318
|
||||
52: char <= 128'h000000000C1C14246444FF0404000000; //419
|
||||
53: char <= 128'h000000007E6060607E0202067C000000; //520
|
||||
54: char <= 128'h000000001E306048764242623C000000; //621
|
||||
55: char <= 128'h000000007E0206040C08181030000000; //722
|
||||
56: char <= 128'h000000003C6242361C6642423C000000; //823
|
||||
57: char <= 128'h000000003C664242661A020478000000; //924
|
||||
58: char <= 128'h00000000000018180000001818000000; //:25
|
||||
59: char <= 128'h00000000000018180000001818083000; //;26
|
||||
60: char <= 128'h00000000000004183060100C06000000; //<27
|
||||
61: char <= 128'h00000000000000007E007E0000000000; //=28
|
||||
62: char <= 128'h000000000000301804060C1020000000; //>29
|
||||
63: char <= 128'h000000301C0606061810001010000000; //?30
|
||||
64: char <= 128'h0000001C224141DDB5A5A5AF94C0403C; //@31
|
||||
65: char <= 128'h00000000181C342426627E43C1000000; //A32
|
||||
66: char <= 128'h000000007C4642467C4242427C000000; //B33
|
||||
67: char <= 128'h000000001E204040404040603E000000; //C34
|
||||
68: char <= 128'h000000007C4642434343424678000000; //D35
|
||||
69: char <= 128'h000000007E6060607E6060607E000000; //E36
|
||||
70: char <= 128'h000000007E6060607E60606060000000; //F37
|
||||
71: char <= 128'h000000001E604040CE4242623E000000; //G38
|
||||
72: char <= 128'h00000000424242427E42424242000000; //H39
|
||||
73: char <= 128'h000000007E181818181818187E000000; //I40
|
||||
74: char <= 128'h000000007C0404040404044478000000; //J41
|
||||
75: char <= 128'h000000004244485070584C4442000000; //K42
|
||||
76: char <= 128'h0000000020202020202020203E000000; //L43
|
||||
77: char <= 128'h000000006266675F5B5BC1C1C1000000; //M44
|
||||
78: char <= 128'h00000000626272525A4A4E4646000000; //N45
|
||||
79: char <= 128'h000000003C6243C3C3C343623C000000; //O46
|
||||
80: char <= 128'h000000007C4642424678404040000000; //P47
|
||||
81: char <= 128'h000000003C6243C3C3C343623C180F00; //Q48
|
||||
82: char <= 128'h000000007C6662667C6C646662000000; //R49
|
||||
83: char <= 128'h000000003E6040601C0602027C000000; //S50
|
||||
84: char <= 128'h000000007F1818181818181818000000; //T51
|
||||
85: char <= 128'h0000000042424242424242623C000000; //U52
|
||||
86: char <= 128'h00000000C14342622624341C18000000; //V53
|
||||
87: char <= 128'h00000000C1C141495B5B766666000000; //W54
|
||||
88: char <= 128'h0000000043663418181C2466C3000000; //X55
|
||||
89: char <= 128'h00000000C14266341C18181818000000; //Y56
|
||||
90: char <= 128'h000000007E02040C181020607E000000; //Z57
|
||||
91: char <= 128'h0000001C10101010101010101010101C; //[58
|
||||
92: char <= 128'h000000402020101008080C0406020000; //\59
|
||||
93: char <= 128'h0000003C0C0C0C0C0C0C0C0C0C0C0C3C; //]60
|
||||
94: char <= 128'h00000000181C24620000000000000000; //^61
|
||||
95: char <= 128'h000000000000000000000000000000FF; //_62
|
||||
96: char <= 128'h00000020100000000000000000000000; //`63
|
||||
97: char <= 128'h0000000000003C06023E42467A000000; //a64
|
||||
98: char <= 128'h0000004040405C62424242427C000000; //b65
|
||||
99: char <= 128'h0000000000001E20604060203E000000; //c66
|
||||
100: char <= 128'h0000000202023E62424242663A000000; //d67
|
||||
101: char <= 128'h0000000000003C62427E40603E000000; //e68
|
||||
102: char <= 128'h0000000F1810107E1010101010000000; //f69
|
||||
103: char <= 128'h0000000000003F66426658403E43423C; //g70
|
||||
104: char <= 128'h0000004040405C624242424242000000; //h71
|
||||
105: char <= 128'h0000001818007808080808087E000000; //i72
|
||||
106: char <= 128'h000000040C007C040404040404040C78; //j73
|
||||
107: char <= 128'h000000606060626C7870686462000000; //k74
|
||||
108: char <= 128'h0000007808080808080808087E000000; //l75
|
||||
109: char <= 128'h000000000000764B4B4B4B4B4B000000; //m76
|
||||
110: char <= 128'h0000000000005C624242424242000000; //n77
|
||||
111: char <= 128'h0000000000003C62424342623C000000; //o78
|
||||
112: char <= 128'h0000000000005C62424242427C404040; //p79
|
||||
113: char <= 128'h0000000000003E62424242663A020202; //q80
|
||||
114: char <= 128'h0000000000006E726360606060000000; //r81
|
||||
115: char <= 128'h0000000000003E20203C06027C000000; //s82
|
||||
116: char <= 128'h000000001010FE10101010101E000000; //t83
|
||||
117: char <= 128'h0000000000004242424242663A000000; //u84
|
||||
118: char <= 128'h00000000000043426624341818000000; //v85
|
||||
119: char <= 128'h000000000000C1C15B5A5E6666000000; //w86
|
||||
120: char <= 128'h00000000000062261C181C2662000000; //x87
|
||||
121: char <= 128'h00000000000043426624341C181830E0; //y88
|
||||
122: char <= 128'h0000000000007E060C1810207E000000; //z89
|
||||
123: char <= 128'h0000000E18101010307010101010180E; //{90
|
||||
124: char <= 128'h00000808080808080808080808080808; //|91
|
||||
125: char <= 128'h00000030180808080C0E080808081830; //}92
|
||||
126: char <= 128'h0000000000000000714B060000000000; //~93
|
||||
default char <= 128'h0;
|
||||
endcase
|
||||
|
||||
endmodule
|
Loading…
x
Reference in New Issue
Block a user