合并ISP-UART和USER-UART,添加Nexys4开发板工程

This commit is contained in:
WangXuan95 2019-02-26 19:50:47 +08:00
parent 0840f54aa6
commit dfb750b8d5
24 changed files with 0 additions and 2162 deletions

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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