远程FPGA虚拟实验平台用SystemVerilog HDL实现存储器

原理

实验材料

就是两个存储器,直接用。

实验内容·用ROM实现七段译码器

学习实验材料里的ROM,并用ROM的形式来写七段译码器ROM_SevenSegDecode,即令ROM的输入为四位数据,输出为八位的用来表示数码管的一串数字。

实验内容·用RAM实现寄存器堆

学习实验材料里的RAM,并用RAM的形式来写寄存器RegisterFile,即令RAM的输入为iWA, iRA1, iRA2, iWD而输出为oRD1, oRD2,再用数码管在virtualboard里显示。

源代码

实验材料·ROM

该实验材料基本照搬到实验内容,所以实验材料就不写了。

实验材料·RAM

VrtualBoard

/** The input port is replaced with an internal signal **/
wire reset  = PB[0];
wire clk    = PB[1];
wire [15:0] write_data  = S[15:0];//一个输入端口,16位数据位
wire [15:0] address = S[31:16];//16位地址位
wire write_enable = S[32];//使能
logic [15:0] read_data;//一个输出端口

/************* The logic of this experiment *************/
RAM #(.ADDRWIDTH(8), .DATAWIDTH(16)) mem(.iClk(clk), .iWR(write_enable), 
    .iAddress(address), .iWriteData(write_data), .oReadData(read_data));

/****** Internal signal assignment to output port *******/
assign HD[0] = read_data[3:0];
assign HD[1] = read_data[7:4];
assign HD[2] = read_data[11:8];
assign HD[3] = read_data[15:12];
assign HD[4] = address[3:0];
assign HD[5] = address[6:4];
// assign HD[6] = address[:];
// assign HD[7] = address[:];
assign L[0] = write_enable;//反正老师没有给实验面板,只能自己幻想一下大概是一堆七段数码管叭

RAM

module RAM
#(  parameter ADDRWIDTH = 6,
	  parameter DATAWIDTH = 32)
(
	input  wire iClk, iWR,
	input  wire [ADDRWIDTH-1:0] iAddress,//6位地址
  input  wire [DATAWIDTH-1:0] iWriteData,//32位输出数据
  output wire [DATAWIDTH-1:0] oReadData//32位输出数据
);
  localparam MEMDEPTH = 1<<ADDRWIDTH; //存储器的字数,为把1左移ADDRWIDTH位,也即b'100000,10位数64
  logic [DATAWIDTH-1:0] mem[0:MEMDEPTH-1];//数组容量64位,每个可以存8位的二进制,一个数组即一个寄存器
  logic [ADDRWIDTH-1:0] read_addr;//用来锁存读地址

  always_ff @(posedge iClk)
  begin
    read_addr <= iAddress;   //读地址锁存,编译器使用FPGA的RAM块生成存储器
    if (iWR)
      mem[iAddress] <= iWriteData;//往寄存器写入地址
  end
  assign oReadData = mem[read_addr]; //从寄存器读地址

  /* initial 为了调试方便可给存储器赋初值,调试成功后将其删除。
      $readmemh("init_data.txt",mem);  // 存储器内容定义在文件中。 */
endmodule

实验内容·用ROM实现七段译码器

VrtualBoard

`default_nettype none 
module VirtualBoard (
    input  logic  CLOCK,      // 10 MHz Input Clock 
    input  logic [19:0] PB,   // 20 Push Buttons, logical 1 when pressed
    input  logic [35:0] S,    // 36 Switches
    output logic [35:0] L,    // 36 LEDs, drive logical 1 to light up
    output logic  [7:0] SD7,  // 8 common anode Seven-segment Display
    output logic  [7:0] SD6,
    output logic  [7:0] SD5,
    output logic  [7:0] SD4,
    output logic  [7:0] SD3,
    output logic  [7:0] SD2,
    output logic  [7:0] SD1,
    output logic  [7:0] SD0
);
/** The input port is replaced with an internal signal **/
wire [3:0] hexData  = S[11:8];

/************* The logic of this experiment *************/
wire [7:0] segData;
ROM_SevenSegDecode ssdecode_inst(.iAddress(hexData), .oData(segData));//输入地址,输出数据

/****** Internal signal assignment to output port *******/
assign SD1 = segData;

改了模块名,其他照搬。

ROM_SevenSegDecode

module ROM_SevenSegDecode
#(  parameter ADDRWIDTH = 4,
	parameter DATAWIDTH = 8)
(
    input  logic [ADDRWIDTH-1:0] iAddress,//输入的地址
    output logic [DATAWIDTH-1:0] oData//输出的数据,8位可以得出是直接写成七段译码器的那个数字
);
    localparam MEMDEPTH = 1<<ADDRWIDTH;//存储器的字数,为把1左移ADDRWIDTH位,也即b'100000,10位数64
    logic [DATAWIDTH-1:0] mem[0:MEMDEPTH-1];//数组容量64位,每个可以存8位的二进制,一个数组即一个寄存器
    assign oData = mem[iAddress];

    initial begin//初始化存储器用来测试数据,实验中也需要这个来完成七段译码器
        //$readmemb("init_mem.txt",mem); //$readmemh是函数,如果文件中的数据是十六进制,用 $readmemh 
        // 也可以采用如下代码代替上面的readmemb,在实验内容里就是要用这种了,用mem数组来赋值
      mem[16'h0000] = 8'b11000000;
		mem[16'h0001] = 8'b11111001;
		mem[16'h0002] = 8'b10100100;
		mem[16'h0003] = 8'b10110000;
		mem[16'h0004] = 8'b10011001;
		mem[16'h0005] = 8'b10010010;
		mem[16'h0006] = 8'b10000010;
		mem[16'h0007] = 8'b11111000;
		mem[16'h0008] = 8'b10000000;
		mem[16'h0009] = 8'b10010000;
		mem[16'h000A] = 8'b10001000;
		mem[16'h000B] = 8'b10000011;
		mem[16'h000C] = 8'b11000110;
		mem[16'h000D] = 8'b10100001;
		mem[16'h000E] = 8'b10000110;
		mem[16'h000F] = 8'b10001110;   
    end
endmodule

实验内容·用RAM实现寄存器堆

VirtualBoard

`default_nettype none 
module VirtualBoard (
    input  logic  CLOCK,      // 10 MHz Input Clock 
    input  logic [19:0] PB,   // 20 Push Buttons, logical 1 when pressed
    input  logic [35:0] S,    // 36 Switches
    output logic [35:0] L,    // 36 LEDs, drive logical 1 to light up
    output logic  [7:0] SD7,  // 8 common anode Seven-segment Display
    output logic  [7:0] SD6,
    output logic  [7:0] SD5,
    output logic  [7:0] SD4,
    output logic  [7:0] SD3,
    output logic  [7:0] SD2,
    output logic  [7:0] SD1,
    output logic  [7:0] SD0
);
/********* Seven-segment decoder instantiation **********/
parameter ADDRWIDTH = 2;
parameter DATAWIDTH = 4;
logic [3:0] HD[7:0];  // 8 hexadecimal display 
SevenSegDecode ssdecode_inst7(.iData(HD[7]), .oSeg(SD7));
SevenSegDecode ssdecode_inst6(.iData(HD[6]), .oSeg(SD6));
SevenSegDecode ssdecode_inst5(.iData(HD[5]), .oSeg(SD5));
SevenSegDecode ssdecode_inst4(.iData(HD[4]), .oSeg(SD4));
SevenSegDecode ssdecode_inst3(.iData(HD[3]), .oSeg(SD3));
SevenSegDecode ssdecode_inst2(.iData(HD[2]), .oSeg(SD2));
SevenSegDecode ssdecode_inst1(.iData(HD[1]), .oSeg(SD1));
SevenSegDecode ssdecode_inst0(.iData(HD[0]), .oSeg(SD0));

/** The input port is replaced with an internal signal **/
wire clk    = PB[1];//根据寄存器堆的实验面板改一下输入的值
wire [DATAWIDTH-1:0] write_data  = S[11:8];
wire [ADDRWIDTH-1:0] address = S[5:4];
wire write_enable = S[6];
wire [ADDRWIDTH-1:0] read_address1 = S[1:0];
wire [ADDRWIDTH-1:0] read_address2 = S[3:2];
wire [DATAWIDTH-1:0] read_data1, read_data2;

/************* The logic of this experiment *************/
RegisterFile #(.ADDRWIDTH(ADDRWIDTH), .DATAWIDTH(DATAWIDTH)) mem(.Clk(clk), .iWE(write_enable), 
    .iWA(address), .iRA1(read_address1), .iRA2(read_address2), .iWD(write_data), .oRD1(read_data1), .oRD2(read_data2));//按照慕课里写的模块来写

/****** Internal signal assignment to output port *******/
assign HD[4] = read_data1;
assign HD[5] = read_data2;

endmodule

RAM(Register)

module RegisterFile
#(  parameter ADDRWIDTH = 5,
	  parameter DATAWIDTH = 32)
(
	input  logic Clk, 
	input  logic iWE,
	input  logic [ADDRWIDTH-1:0] iWA, iRA1, iRA2,
	input  logic [DATAWIDTH-1:0] iWD,
	output logic [DATAWIDTH-1:0] oRD1, oRD2
);
localparam MEMDEPTH = 1<<ADDRWIDTH; //存储器的字数 
logic [DATAWIDTH-1:0] mem[0:MEMDEPTH-1];
logic [ADDRWIDTH-1:0] read_addr1, read_addr2;

always_ff @(posedge Clk)
begin
	read_addr1 <= iRA1;   //读地址锁存,编译器使用FPGA的RAM块生成存储器
	read_addr2 <= iRA2;
	if (iWE && iWA!=0)//寄存器0不能写入数据
		mem[iWA] <= iWD;
end
assign oRD1 = mem[iRA1]; //输出
assign oRD2 = mem[iRA2]; 
initial begin//初始化寄存器0为0
      mem[5'b0] = 32'b0;
end
endmodule

测试/保存/提交

七段译码器的jvp去之前的实验里抓过来,这次实验数据回放记得直接提交,啥也别干就好,说实话前面的每一次也都是这样拿满分,离谱,这次终于在慕课提到了

  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值