You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

80 lines
2.6 KiB
Verilog

// 写优先: 立即把当前din写入值 输出到dout接口, 相当于把din和dout连接起来了
// 读优先: 如果本身没有值会直接输出din到dout接口, 如果由值, 会把旧的值输出到dout接口
// 不做任何改变: din和dout接口没有相关性
// 该实验会在复位之后启动ram核, 然后一个计数器累加从0~15, 其中0~7的时候高电平进行写(同样写0~7), 8~15低电平进行读取(把写的读出来)
module ram(
(*mark_debug="true"*)input wire sys_clk, // U18
(*mark_debug="true"*)input wire sys_rst //J15
);
(*mark_debug="true"*)reg [2:0]ram_addr; // 数据深度为8, 地址变化范围 0~7就行了, 每个时钟周期加1, 直到溢出从0开始
(*mark_debug="true"*)reg [2:0]in_ram_data; // 数据宽度为3, 假想写入的数据, 数据变化范围是0~7, 只有在 ram_rw 是写入的时候进行累加并写入地址内
(*mark_debug="true"*)wire [2:0]out_ram_data;
reg ram_en;
always @(posedge sys_clk or negedge sys_rst) begin
if (!sys_rst) begin
ram_en <= 1'b0;
end
// 只有在复位之后, 才允许启动ram
else begin
ram_en <= 1'b1;
end
end
(*mark_debug="true"*)reg [7:0]counter; // 计数到15 清零, 变化范围 0~15, 0~7是写, 8~15是读
wire ram_rw; // 是否可写/可读
(*mark_debug="true"*)assign ram_rw = ram_en && (counter <= 8'b111); // 计数器 分成读写各占一半时间
always @(posedge sys_clk or negedge sys_rst) begin
if (!sys_rst) begin
counter <= 8'b0;
end
// 没有启用ram禁止计数
else if (ram_en == 1'b0 || counter == 8'b1111) begin
counter <= 8'b0;
end
else begin
counter <= counter + 8'b1;
end
end
always @(posedge sys_clk or negedge sys_rst) begin
if (!sys_rst) begin
ram_addr <= 3'b0;
end
else if (ram_en && ram_addr < 3'b111) begin
ram_addr <= ram_addr + 3'b1;
end
else begin
ram_addr <= 3'b0;
end
end
always @(posedge sys_clk or negedge sys_rst) begin
if (!sys_rst) begin
in_ram_data <= 3'b0;
end
// 如果是写, 并且还没到最大数
else if (ram_rw && in_ram_data < 3'b111) begin
in_ram_data <= in_ram_data + 3'b1;
end
else begin
in_ram_data <= 3'b0;
end
end
blk_mem_gen_0 _blk_mem_gen_0 (
.clka(sys_clk), // input wire clka
.ena(ram_en), // input wire ena
.wea(ram_rw), // input wire [0 : 0] wea
.addra(ram_addr), // input wire [2 : 0] addra
.dina(in_ram_data), // input wire [2 : 0] dina
.douta(out_ram_data) // output wire [2 : 0] douta
);
endmodule