当前位置: 首页 > news >正文

18new - when

package componentsimport chisel3._import chisel3.util._import components.Constants._ // 确保导入常量/** * IF/ID流水线寄存器 */class IFIDBundle extends Bundle {  val inst = UInt(32.W)  val pc   = UInt(32.W)}/** * ID/EX流水线寄存器 */class IDEXBundle extends Bundle {  val pc      = UInt(32.W)  val alu_a   = UInt(32.W)  val alu_b   = UInt(32.W)  val rd_addr = UInt(5.W)  val rs1_addr = UInt(5.W)  val rs2_addr = UInt(5.W)  val ctrl    = new ControlSigs}/** * EX/MEM流水线寄存器 */class EXMEMBundle extends Bundle {  val pc           = UInt(32.W)  val alu_out      = UInt(32.W)  val alu_b        = UInt(32.W) // 用于访存写数据 (已前递)  val rd_addr      = UInt(5.W)  val alu_zero     = Bool()  val ctrl         = new ControlSigs}/** * MEM/WB流水线寄存器 */class MEMWBBundle extends Bundle {  val pc           = UInt(32.W)  val wb_data      = UInt(32.W)  val rd_addr      = UInt(5.W)  val reg_write_en = Bool()}/** * 主CPU模块 (最终重构版) */class MyCPU extends Module {  val io = IO(new Bundle {    val rst = Input(Bool())    val imem_addr = Output(UInt(32.W))    val imem_inst = Input(UInt(32.W))    val debug_reg_out = Output(Vec(32, UInt(32.W)))    val debug_pc_out  = Output(UInt(32.W))    val total_cycles = Output(UInt(32.W))    val total_instructions = Output(UInt(32.W))    val stall_cycles = Output(UInt(32.W))    val dmem_addr = Output(UInt(32.W))    val dmem_write_data = Output(UInt(32.W))    val dmem_write_en = Output(Bool())    val dmem_read_en = Output(Bool())    val dmem_size = Output(UInt(2.W))    val dmem_read_data = Input(UInt(32.W))    val stall_from_bus = Input(Bool())    val debug_next_pc = Output(UInt(32.W))    val debug_pc_write_en = Output(Bool())  })  // 模块实例化  val alu     = Module(new ALU(32))  val regFile = withReset(io.rst) { Module(new RegFile) }  val decoder = Module(new Decoder)  val immGen  = Module(new ImmGen)  val forwardingUnit = Module(new ForwardingUnit)  val hazardDetection = Module(new HazardDetection)  // 流水线寄存器  val ifid_reg  = RegInit(0.U.asTypeOf(new IFIDBundle))  val idex_reg  = RegInit(0.U.asTypeOf(new IDEXBundle))  val exmem_reg = RegInit(0.U.asTypeOf(new EXMEMBundle))  val memwb_reg = RegInit(0.U.asTypeOf(new MEMWBBundle))  val idex_imm = RegInit(0.U(32.W))  // 性能计数器  val total_cycles = RegInit(0.U(32.W))  val total_instructions = RegInit(0.U(32.W))  val stall_cycles = RegInit(0.U(32.W))  val last_counted_pc = RegInit(0.U(32.W))  // =================================================================  // ========== IF/ID/EX 信号 (按数据流顺序定义) ==========  // =================================================================  // --- IF阶段信号 ---  val pc = RegInit("h_80000000".U(32.W))  val pc_next = RegInit("h_80000000".U(32.W))  val pc_base = "h_80000000".U(32.W)  val pc_max = "h_807FFFFF".U(32.W)  val ex_jump_taken_reg = RegInit(false.B)  val ex_jump_target_reg = RegInit(0.U(32.W))  // --- ID阶段信号 ---  val id_inst  = ifid_reg.inst  val id_pc    = ifid_reg.pc  decoder.io.inst := id_inst  val ctrl_sigs = decoder.io.sigs  val rd_addr  = id_inst(4, 0)  val rj_addr  = id_inst(9, 5)  val rk_addr  = id_inst(14, 10)  val actual_rs2_addr = Mux(ctrl_sigs.branch_type.orR, rd_addr, Mux(ctrl_sigs.mem_write_en, rd_addr, rk_addr))  // --- EX阶段信号 ---  val ex_ctrl = idex_reg.ctrl  val alu_a_forwarded = MuxCase(idex_reg.alu_a, Seq((forwardingUnit.io.forward_a === 1.U) -> exmem_reg.alu_out, (forwardingUnit.io.forward_a === 2.U) -> memwb_reg.wb_data))  val alu_b_forwarded = MuxCase(idex_reg.alu_b, Seq((forwardingUnit.io.forward_b === 1.U) -> exmem_reg.alu_out, (forwardingUnit.io.forward_b === 2.U) -> memwb_reg.wb_data))  val alu_a_final = MuxCase(alu_a_forwarded, Seq(    (ex_ctrl.alu_a_sel === A_ZERO) -> 0.U(32.W),    (ex_ctrl.alu_a_sel === A_PC)   -> idex_reg.pc  ))  val alu_b_final = Mux(ex_ctrl.alu_b_sel === B_IMM, idex_imm, alu_b_forwarded)  alu.io.op := ex_ctrl.alu_op  alu.io.a  := alu_a_final  alu.io.b  := alu_b_final  val branch_taken = (ex_ctrl.branch_type === BR_JUMP) || (ex_ctrl.branch_type === BR_EQ && alu.io.zero) || (ex_ctrl.branch_type === BR_NE && !alu.io.zero)  // =================================================================  // ========== 冒险检测与流水线控制 ==========  // =================================================================  // --- 冒险检测单元连接 ---  hazardDetection.io.ex_mem_read := idex_reg.ctrl.mem_read_en  hazardDetection.io.ex_rd_addr := idex_reg.rd_addr  hazardDetection.io.id_rs1_addr := rj_addr  hazardDetection.io.id_rs2_addr := rk_addr // 简化处理, 见之前讨论  hazardDetection.io.ex_jump_taken := branch_taken  // --- 流水线控制信号 ---  val stall_if = hazardDetection.io.stall_if || io.stall_from_bus  val stall_id = hazardDetection.io.stall_id  val flush_if = hazardDetection.io.flush_if  val flush_id = hazardDetection.io.flush_id  val flush_ex = hazardDetection.io.flush_ex || io.stall_from_bus  // =================================================================  // ========== 流水线寄存器更新 ==========  // =================================================================  // --- PC更新逻辑 ---  when(io.rst) {    pc := pc_base    pc_next := pc_base + 4.U    ex_jump_taken_reg := false.B    ex_jump_target_reg := 0.U  } .elsewhen(!stall_if) {    pc := pc_next    val next_pc_candidate = Mux(ex_jump_taken_reg, ex_jump_target_reg, pc + 4.U)    pc_next := Mux(next_pc_candidate < pc_base, pc_base, Mux(next_pc_candidate > pc_max, pc_max, next_pc_candidate))    ex_jump_taken_reg := false.B  }  // --- IF/ID寄存器更新 ---  io.imem_addr := pc_next  val inst_reg = RegNext(io.imem_inst, 0.U)  when(flush_if) {    ifid_reg.inst := 0.U    ifid_reg.pc   := 0.U  } .elsewhen(stall_if) { /* 保持不变 */ }  .otherwise {    ifid_reg.inst := inst_reg    ifid_reg.pc   := RegNext(pc, "h_80000000".U(32.W))  }  // --- ID/EX寄存器更新 ---  immGen.io.inst := id_inst  immGen.io.imm_type := ctrl_sigs.imm_type  regFile.io.rs1_addr := rj_addr  regFile.io.rs2_addr := actual_rs2_addr  when(flush_ex) {    idex_reg := 0.U.asTypeOf(new IDEXBundle)    idex_imm := 0.U  } .elsewhen(stall_id) { /* 保持不变 */ }  .otherwise {    idex_reg.pc      := id_pc    idex_reg.alu_a   := regFile.io.rs1_data    idex_reg.alu_b   := regFile.io.rs2_data    idex_reg.rd_addr := rd_addr    idex_reg.rs1_addr := rj_addr    idex_reg.rs2_addr := actual_rs2_addr    idex_reg.ctrl    := ctrl_sigs    idex_imm         := immGen.io.imm_out  }  // --- EX/MEM寄存器更新 ---  val jump_target = alu.io.out  val target_clamped = Mux(jump_target < pc_base, pc_base, Mux(jump_target > pc_max, pc_max, jump_target))  when(branch_taken) {    ex_jump_taken_reg := true.B    ex_jump_target_reg := target_clamped  }  exmem_reg.pc           := idex_reg.pc  exmem_reg.alu_out      := alu.io.out  exmem_reg.alu_b        := alu_b_forwarded // <<<<<<<< 已修正潜在Bug  exmem_reg.rd_addr      := idex_reg.rd_addr  exmem_reg.alu_zero     := alu.io.zero  exmem_reg.ctrl         := ex_ctrl  // =================================================================  // ========== MEM/WB 阶段 ==========  // =================================================================  // --- MEM阶段 ---  val mem_ctrl = exmem_reg.ctrl  io.dmem_addr := exmem_reg.alu_out  io.dmem_write_data := exmem_reg.alu_b  io.dmem_write_en := mem_ctrl.mem_write_en  io.dmem_read_en := mem_ctrl.mem_read_en  io.dmem_size := mem_ctrl.mem_size  val wb_data = MuxCase(exmem_reg.alu_out, Seq(    (exmem_reg.ctrl.wb_sel === WB_MEM) -> io.dmem_read_data,    (exmem_reg.ctrl.wb_sel === WB_PC4) -> (exmem_reg.pc + 4.U)  ))  // --- MEM/WB寄存器更新 ---  memwb_reg.pc           := exmem_reg.pc  memwb_reg.wb_data      := wb_data  memwb_reg.rd_addr      := exmem_reg.rd_addr  memwb_reg.reg_write_en := exmem_reg.ctrl.reg_write_en  // --- WB阶段 ---  forwardingUnit.io.ex_rs1_addr := idex_reg.rs1_addr  forwardingUnit.io.ex_rs2_addr := idex_reg.rs2_addr  forwardingUnit.io.mem_rd_addr := exmem_reg.rd_addr  forwardingUnit.io.mem_reg_write := exmem_reg.ctrl.reg_write_en  forwardingUnit.io.wb_rd_addr := memwb_reg.rd_addr  forwardingUnit.io.wb_reg_write := memwb_reg.reg_write_en  val allowWriteBack = RegInit(false.B)  when (io.rst) { allowWriteBack := false.B } .otherwise { allowWriteBack := true.B }  regFile.io.rd_addr := memwb_reg.rd_addr  regFile.io.rd_data := memwb_reg.wb_data  regFile.io.rd_en   := (memwb_reg.reg_write_en && allowWriteBack)  // =================================================================  // ========== 性能计数器与调试输出 ==========  // =================================================================  when(!io.rst) {    total_cycles := total_cycles + 1.U    when((stall_if || stall_id) && (stall_cycles < total_cycles)) { stall_cycles := stall_cycles + 1.U }    val wb_pc_valid = (memwb_reg.pc =/= 0.U) && (memwb_reg.pc >= pc_base) && (memwb_reg.pc <= pc_max)    val wb_pc_changed = (memwb_reg.pc =/= last_counted_pc) && wb_pc_valid && allowWriteBack    when(wb_pc_changed) {      last_counted_pc := memwb_reg.pc      total_instructions := total_instructions + 1.U    }  } .otherwise {    last_counted_pc := 0.U  }  io.debug_reg_out := regFile.io.debug_regs_out  io.debug_pc_out  := pc  io.debug_next_pc := pc_next  io.debug_pc_write_en := !stall_if  io.total_cycles := total_cycles  io.total_instructions := total_instructions  io.stall_cycles := stall_cycles}
`default_nettype nonemodule thinpad_top(    input wire clk_50M,           //50MHz 时钟输入    input wire clk_11M0592,       //11.0592MHz 时钟输入(备用,可不用)    input wire clock_btn,         //BTN5手动时钟按钮开关,带消抖电路,按下时为1    input wire reset_btn,         //BTN6手动复位按钮开关,带消抖电路,按下时为1    input  wire[3:0]  touch_btn,  //BTN1~BTN4,按钮开关,按下时为1    input  wire[31:0] dip_sw,     //32位拨码开关,拨到"ON"时为1    output wire[15:0] leds,       //16位LED,输出时1点亮    output wire[7:0]  dpy0,       //数码管低位信号,包括小数点,输出1点亮    output wire[7:0]  dpy1,       //数码管高位信号,包括小数点,输出1点亮    //BaseRAM信号    inout wire[31:0] base_ram_data,  //BaseRAM数据,低8位与CPLD串口控制器共享    output wire[19:0] base_ram_addr, //BaseRAM地址    output wire[3:0] base_ram_be_n,  //BaseRAM字节使能,低有效。如果不使用字节使能,请保持为0    output wire base_ram_ce_n,       //BaseRAM片选,低有效    output wire base_ram_oe_n,       //BaseRAM读使能,低有效    output wire base_ram_we_n,       //BaseRAM写使能,低有效    //ExtRAM信号    inout wire[31:0] ext_ram_data,  //ExtRAM数据    output wire[19:0] ext_ram_addr, //ExtRAM地址    output wire[3:0] ext_ram_be_n,  //ExtRAM字节使能,低有效。如果不使用字节使能,请保持为0    output wire ext_ram_ce_n,       //ExtRAM片选,低有效    output wire ext_ram_oe_n,       //ExtRAM读使能,低有效    output wire ext_ram_we_n,       //ExtRAM写使能,低有效    //直连串口信号    output wire txd,  //直连串口发送端    input  wire rxd,  //直连串口接收端    //Flash存储器信号,参考 JS28F640 芯片手册    output wire [22:0]flash_a,      //Flash地址,a0仅在8bit模式有效,16bit模式无意义    inout  wire [15:0]flash_d,      //Flash数据    output wire flash_rp_n,         //Flash复位信号,低有效    output wire flash_vpen,         //Flash写保护信号,低电平时不能擦除、烧写    output wire flash_ce_n,         //Flash片选信号,低有效    output wire flash_oe_n,         //Flash读使能信号,低有效    output wire flash_we_n,         //Flash写使能信号,低有效    output wire flash_byte_n,       //Flash 8bit模式选择,低有效。在使用flash的16位模式时请设为1    //图像输出信号    output wire[2:0] video_red,    //红色像素,3位    output wire[2:0] video_green,  //绿色像素,3位    output wire[1:0] video_blue,   //蓝色像素,2位    output wire video_hsync,       //行同步(水平同步)信号    output wire video_vsync,       //场同步(垂直同步)信号    output wire video_clk,         //像素时钟输出    output wire video_de           //行数据有效信号,用于区分消隐区);// =========== CPU接口信号定义 ===========wire cpu_clock;wire cpu_reset;wire cpu_io_rst;wire [31:0] cpu_io_imem_addr;wire [31:0] cpu_io_imem_inst;wire [31:0] cpu_io_dmem_addr;wire [31:0] cpu_io_dmem_write_data;wire cpu_io_dmem_write_en;wire cpu_io_dmem_read_en;wire [1:0] cpu_io_dmem_size;wire [31:0] cpu_io_dmem_read_data;// =========== PLL分频 ===========wire locked, clk_10M, clk_20M;pll_example clock_gen (    .clk_in1(clk_50M),  // 外部时钟输入    .clk_out1(clk_10M), // 时钟输出1    .clk_out2(clk_20M), // 时钟输出2    .reset(reset_btn), // PLL复位输入    .locked(locked)    // PLL锁定指示输出);reg reset_of_clk10M;// 异步复位,同步释放always @(posedge clk_10M or negedge locked) begin    if (~locked) reset_of_clk10M <= 1'b1;    else         reset_of_clk10M <= 1'b0;end// =========== 时钟和复位适配 ===========assign cpu_clock = clk_10M;assign cpu_reset = reset_of_clk10M;  // Chisel reset是低电平有效assign cpu_io_rst = reset_of_clk10M;// =========== CPU实例化 ===========MyCPU u_cpu (    .clock(cpu_clock),    .reset(cpu_reset),      .io_rst(cpu_io_rst),    .io_imem_addr(cpu_io_imem_addr),    .io_imem_inst(cpu_io_imem_inst),    .io_dmem_addr(cpu_io_dmem_addr),    .io_dmem_write_data(cpu_io_dmem_write_data),    .io_dmem_write_en(cpu_io_dmem_write_en),    .io_dmem_read_en(cpu_io_dmem_read_en),    .io_dmem_size(cpu_io_dmem_size),    .io_dmem_read_data(cpu_io_dmem_read_data),    .io_debug_reg_out_0(),    .io_debug_reg_out_1(),    .io_debug_reg_out_2(),    .io_debug_reg_out_3(),    .io_debug_reg_out_4(),    .io_debug_reg_out_5(),    .io_debug_reg_out_6(),    .io_debug_reg_out_7(),    .io_debug_reg_out_8(),    .io_debug_reg_out_9(),    .io_debug_reg_out_10(),    .io_debug_reg_out_11(),    .io_debug_reg_out_12(),    .io_debug_reg_out_13(),    .io_debug_reg_out_14(),    .io_debug_reg_out_15(),    .io_debug_reg_out_16(),    .io_debug_reg_out_17(),    .io_debug_reg_out_18(),    .io_debug_reg_out_19(),    .io_debug_reg_out_20(),    .io_debug_reg_out_21(),    .io_debug_reg_out_22(),    .io_debug_reg_out_23(),    .io_debug_reg_out_24(),    .io_debug_reg_out_25(),    .io_debug_reg_out_26(),    .io_debug_reg_out_27(),    .io_debug_reg_out_28(),    .io_debug_reg_out_29(),    .io_debug_reg_out_30(),    .io_debug_reg_out_31(),    .io_debug_pc_out(),    .io_debug_next_pc(),    .io_debug_pc_write_en(),    .io_total_cycles(),    .io_total_instructions(),    .io_stall_cycles());// =========== 指令端口(直接挂在 BaseRAM 上) ===========localparam MEM_BASE = 32'h8000_0000;localparam MEM_END  = 32'h807F_FFFF;wire imem_access = (cpu_io_imem_addr >= MEM_BASE) && (cpu_io_imem_addr <= MEM_END);wire [11:0] imem_low = cpu_io_imem_addr[11:0];wire imem_use_base = imem_access && (imem_low < 12'h400);wire [19:0] imem_base_addr = cpu_io_imem_addr[21:2];reg [31:0] imem_data_reg;always @(posedge clk_10M or posedge reset_of_clk10M) begin    if (reset_of_clk10M)        imem_data_reg <= 32'h0;    else if (imem_use_base)        imem_data_reg <= base_ram_data;endassign cpu_io_imem_inst = imem_data_reg;// BaseRAM 控制信号(指令读)wire base_ce_n_imem = ~imem_use_base;wire base_oe_n_imem = ~imem_use_base;wire base_we_n_imem = 1'b1;wire [19:0] base_addr_imem = imem_base_addr;// =========== 数据端口通过 1x2 Bridge ===========wire [19:0] bridge_base_addr;wire [19:0] bridge_ext_addr;wire [3:0]  bridge_base_be_n;wire [3:0]  bridge_ext_be_n;wire bridge_base_ce_n;wire bridge_base_oe_n;wire bridge_base_we_n;wire bridge_ext_ce_n;wire bridge_ext_oe_n;wire bridge_ext_we_n;wire bridge_base_drive_en;wire [31:0] bridge_base_drive_data;wire bridge_ext_drive_en;wire [31:0] bridge_ext_drive_data;wire bridge_base_active;MemBridge1x2 u_mem_bridge (    .clk          (clk_10M),    .rst          (reset_of_clk10M),    .addr         (cpu_io_dmem_addr),    .wdata        (cpu_io_dmem_write_data),    .write_en     (cpu_io_dmem_write_en),    .read_en      (cpu_io_dmem_read_en),    .size         (cpu_io_dmem_size),    .base_data_in (base_ram_data),    .ext_data_in  (ext_ram_data),    .rdata        (cpu_io_dmem_read_data),    .base_addr    (bridge_base_addr),    .base_be_n    (bridge_base_be_n),    .base_ce_n    (bridge_base_ce_n),    .base_oe_n    (bridge_base_oe_n),    .base_we_n    (bridge_base_we_n),    .base_drive_en   (bridge_base_drive_en),    .base_drive_data (bridge_base_drive_data),    .base_active     (bridge_base_active),    .ext_addr     (bridge_ext_addr),    .ext_be_n     (bridge_ext_be_n),    .ext_ce_n     (bridge_ext_ce_n),    .ext_oe_n     (bridge_ext_oe_n),    .ext_we_n     (bridge_ext_we_n),    .ext_drive_en   (bridge_ext_drive_en),    .ext_drive_data (bridge_ext_drive_data));// BaseRAM 总线仲裁(指令优先)assign base_ram_addr = bridge_base_active ? bridge_base_addr : base_addr_imem;assign base_ram_ce_n = base_ce_n_imem & bridge_base_ce_n;assign base_ram_oe_n = base_oe_n_imem & bridge_base_oe_n;assign base_ram_we_n = bridge_base_we_n;assign base_ram_be_n = bridge_base_active ? bridge_base_be_n : 4'b0000;assign base_ram_data = bridge_base_drive_en ? bridge_base_drive_data : 32'hZZZZ_ZZZZ;// ExtRAM 直接来自 Bridgeassign ext_ram_addr   = bridge_ext_addr;assign ext_ram_be_n   = bridge_ext_be_n;assign ext_ram_ce_n   = bridge_ext_ce_n;assign ext_ram_oe_n   = bridge_ext_oe_n;assign ext_ram_we_n   = bridge_ext_we_n;assign ext_ram_data   = bridge_ext_drive_en ? bridge_ext_drive_data : 32'hZZZZ_ZZZZ;// =========== 简易IO占空 ===========assign leds = 16'h0;assign dpy0 = 8'h0;assign dpy1 = 8'h0;assign txd  = 1'b1;assign flash_a = 23'h0;assign flash_rp_n = 1'b1;assign flash_vpen = 1'b1;assign flash_ce_n = 1'b1;assign flash_oe_n = 1'b1;assign flash_we_n = 1'b1;assign flash_byte_n = 1'b1;assign flash_d = 16'hZZZZ;assign video_red   = 3'h0;assign video_green = 3'h0;assign video_blue  = 2'h0;assign video_hsync = 1'b0;assign video_vsync = 1'b0;assign video_clk   = 1'b0;assign video_de    = 1'b0;endmodule// ==================== 1x2 Memory Bridge ====================module MemBridge1x2(    input  wire        clk,    input  wire        rst,    input  wire [31:0] addr,    input  wire [31:0] wdata,    input  wire        write_en,    input  wire        read_en,    input  wire [1:0]  size,    input  wire [31:0] base_data_in,    input  wire [31:0] ext_data_in,    output reg  [31:0] rdata,    output wire [19:0] base_addr,    output reg  [3:0]  base_be_n,    output wire        base_ce_n,    output wire        base_oe_n,    output wire        base_we_n,    output wire        base_drive_en,    output wire [31:0] base_drive_data,    output wire        base_active,    output wire [19:0] ext_addr,    output reg  [3:0]  ext_be_n,    output wire        ext_ce_n,    output wire        ext_oe_n,    output wire        ext_we_n,    output wire        ext_drive_en,    output wire [31:0] ext_drive_data);    localparam MEM_BASE = 32'h8000_0000;    localparam MEM_END  = 32'h807F_FFFF;    wire addr_valid = (addr >= MEM_BASE) && (addr <= MEM_END);    wire [11:0] low = addr[11:0];    wire select_base = addr_valid && (low < 12'h400);    wire select_ext  = addr_valid && (low >= 12'h400);    reg [31:0] write_aligned;    reg [3:0]  write_mask_n;    always @(*) begin        case (size)            2'd0: begin                write_aligned = wdata << (8 * addr[1:0]);                write_mask_n  = ~(4'b0001 << addr[1:0]);            end            2'd1: begin                write_aligned = addr[1] ?                    {wdata[15:0], 16'h0} :                    {16'h0, wdata[15:0]};                write_mask_n  = addr[1] ? 4'b0011 : 4'b1100;            end            default: begin                write_aligned = wdata;                write_mask_n  = 4'b0000;            end        endcase    end    function automatic [31:0] format_read;        input [31:0] data_in;        input [1:0]  size_in;        input [1:0]  addr_low;        begin            case (size_in)                2'd0: begin                    case (addr_low)                        2'd0: format_read = {24'h0, data_in[7:0]};                        2'd1: format_read = {24'h0, data_in[15:8]};                        2'd2: format_read = {24'h0, data_in[23:16]};                        default: format_read = {24'h0, data_in[31:24]};                    endcase                end                2'd1: begin                    format_read = addr_low[1] ?                        {16'h0, data_in[31:16]} :                        {16'h0, data_in[15:0]};                end                default: format_read = data_in;            endcase        end    endfunction    wire [31:0] base_read_data = format_read(base_data_in, size, addr[1:0]);    wire [31:0] ext_read_data  = format_read(ext_data_in,  size, addr[1:0]);    always @(posedge clk or posedge rst) begin        if (rst)            rdata <= 32'h0;        else if (select_base && read_en)            rdata <= base_read_data;        else if (select_ext && read_en)            rdata <= ext_read_data;        else if (!read_en)            rdata <= 32'h0;    end    assign base_addr = addr[21:2];    assign ext_addr  = addr[21:2];    assign base_ce_n = ~(select_base && (read_en || write_en));    assign base_oe_n = ~(select_base && read_en);    assign base_we_n = ~(select_base && write_en);    assign base_drive_en   = select_base && write_en;    assign base_drive_data = write_aligned;    assign base_active     = select_base && (read_en || write_en);    assign ext_ce_n = ~(select_ext && (read_en || write_en));    assign ext_oe_n = ~(select_ext && read_en);    assign ext_we_n = ~(select_ext && write_en);    assign ext_drive_en   = select_ext && write_en;    assign ext_drive_data = write_aligned;    always @(*) begin        if (select_base) begin            base_be_n = write_en ? write_mask_n : 4'b0000;        end else begin            base_be_n = 4'b1111;        end        if (select_ext) begin            ext_be_n = write_en ? write_mask_n : 4'b0000;        end else begin            ext_be_n = 4'b1111;        end    endendmodule
http://www.rkmt.cn/news/53149.html

相关文章:

  • linux apache 服务器搭建
  • 2025杭州最好的留学中介是哪家公司
  • 2025年11月国内PMS酒店管理系统公司排行榜:智能化升级的十大优选方案
  • 687
  • 视频汇聚平台EasyCVR构筑新时代边防哨所的“智能视觉防线”
  • 从“人防”到“技防”:视频融合平台EasyCVR打造快递代收点智能视频监控网
  • 2025年塑料回收行业领军企业排名出炉,塑料回收供应商TOP企业引领行业技术新高度
  • 2025杭州最好的留学中介排名榜单
  • 2025办理出国留学机构哪家好
  • 21、LIKE 子句详解
  • 2025年国内锯床公司权威排名榜单:成都鸿远机械有限公司排名首位
  • 2025成都留学机构十大排名
  • show 语法
  • 罗氏线圈积分技术:从理论到工程的精确电流重构
  • linux android 搭建
  • AI 十大论文精讲(五):RAG——让大模型 “告别幻觉、实时更新” 的检索增强生成秘籍
  • 2025年耐高压硅胶线批发厂家权威推荐榜单:硅胶线哪家质量好/硅胶多芯线/陶瓷化硅胶线源头厂家精选
  • AI 十大论文精讲(三):RLHF 范式奠基 ——InstructGPT 如何让大模型 “听懂人话”
  • 【LVGL】圆弧部件
  • 2025年电机生产流水线实力厂家权威推荐:电机生产线/无刷电机自动生产线/电机自动化生产源头厂家精选
  • [题解]BYOI Round 1 T1~T2
  • 服务器接口调用微信小程序获取手机号接口报:The SSL connection could not be established, see inner exception.
  • 2025留学美国被开除怎么办?申诉挽回/学业急救/身份保留/转学规划/签证补救机构哪家强
  • WPS用Qt还情有可原
  • 2025年评价高的UV 软膜广告灯箱厂家最新TOP排行
  • 2025年山西口碑好的纪念馆展示柜定制厂家排行Top10推荐
  • C# 14 新功能全面解析:提升生产力与性能的革命性更新
  • 2025年优秀的软件行业体系认证三体系认证品牌实力推荐榜
  • 2025年11月中国枸杞企业口碑推荐榜单
  • 学业危机速看!2025美国紧急转学机构哪家好,学分对接/院校适配全解析