diff --git a/ip_1_port_ram/ram.v b/ip_1_port_ram/ram.v index e69de29..d8c7751 100644 --- a/ip_1_port_ram/ram.v +++ b/ip_1_port_ram/ram.v @@ -0,0 +1,82 @@ +// 写优先: 立即把当前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就行了 +(*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 +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 \ No newline at end of file diff --git a/ip_1_port_ram/ram.v.out b/ip_1_port_ram/ram.v.out new file mode 100644 index 0000000..ef8e995 --- /dev/null +++ b/ip_1_port_ram/ram.v.out @@ -0,0 +1,148 @@ +#! /c/Source/iverilog-install/bin/vvp +:ivl_version "12.0 (devel)" "(s20150603-1539-g2693dd32b)"; +:ivl_delay_selection "TYPICAL"; +:vpi_time_precision + 0; +:vpi_module "C:\iverilog\lib\ivl\system.vpi"; +:vpi_module "C:\iverilog\lib\ivl\vhdl_sys.vpi"; +:vpi_module "C:\iverilog\lib\ivl\vhdl_textio.vpi"; +:vpi_module "C:\iverilog\lib\ivl\v2005_math.vpi"; +:vpi_module "C:\iverilog\lib\ivl\va_math.vpi"; +S_000001d72665a990 .scope module, "tb_ram" "tb_ram" 2 1; + .timescale 0 0; + .port_info 0 /INPUT 1 "sys_clk"; + .port_info 1 /INPUT 1 "sys_rst"; +L_000001d7267330e0 .functor AND 1, v000001d72665ab20_0, L_000001d7266564d0, C4<1>, C4<1>; +L_000001d7266eb018 .functor BUFT 1, C4<00000111>, C4<0>, C4<0>, C4<0>; +v000001d726694ac0_0 .net/2u *"_ivl_0", 7 0, L_000001d7266eb018; 1 drivers +v000001d726656bf0_0 .net *"_ivl_2", 0 0, L_000001d7266564d0; 1 drivers +v000001d72665a060_0 .var "counter", 7 0; +v000001d7266a4530_0 .var "ram_addr", 2 0; +v000001d7266a45d0_0 .var "ram_data", 2 0; +v000001d72665ab20_0 .var "ram_en", 0 0; +v000001d72665abc0_0 .net "ram_rw", 0 0, L_000001d7267330e0; 1 drivers +o000001d7266aa0e8 .functor BUFZ 1, C4; HiZ drive +v000001d726656390_0 .net "sys_clk", 0 0, o000001d7266aa0e8; 0 drivers +o000001d7266aa118 .functor BUFZ 1, C4; HiZ drive +v000001d726656430_0 .net "sys_rst", 0 0, o000001d7266aa118; 0 drivers +E_000001d726658840/0 .event negedge, v000001d726656430_0; +E_000001d726658840/1 .event posedge, v000001d726656390_0; +E_000001d726658840 .event/or E_000001d726658840/0, E_000001d726658840/1; +L_000001d7266564d0 .cmp/ge 8, L_000001d7266eb018, v000001d72665a060_0; + .scope S_000001d72665a990; +T_0 ; + %wait E_000001d726658840; + %load/vec4 v000001d726656430_0; + %nor/r; + %flag_set/vec4 8; + %jmp/0xz T_0.0, 8; + %pushi/vec4 0, 0, 1; + %assign/vec4 v000001d72665ab20_0, 0; + %jmp T_0.1; +T_0.0 ; + %pushi/vec4 1, 0, 1; + %assign/vec4 v000001d72665ab20_0, 0; +T_0.1 ; + %jmp T_0; + .thread T_0; + .scope S_000001d72665a990; +T_1 ; + %wait E_000001d726658840; + %load/vec4 v000001d726656430_0; + %nor/r; + %flag_set/vec4 8; + %jmp/0xz T_1.0, 8; + %pushi/vec4 0, 0, 8; + %assign/vec4 v000001d72665a060_0, 0; + %jmp T_1.1; +T_1.0 ; + %load/vec4 v000001d72665ab20_0; + %cmpi/e 0, 0, 1; + %jmp/1 T_1.4, 4; + %flag_mov 8, 4; + %load/vec4 v000001d72665a060_0; + %cmpi/e 15, 0, 8; + %flag_or 4, 8; +T_1.4; + %jmp/0xz T_1.2, 4; + %pushi/vec4 0, 0, 8; + %assign/vec4 v000001d72665a060_0, 0; + %jmp T_1.3; +T_1.2 ; + %load/vec4 v000001d72665a060_0; + %addi 1, 0, 8; + %assign/vec4 v000001d72665a060_0, 0; +T_1.3 ; +T_1.1 ; + %jmp T_1; + .thread T_1; + .scope S_000001d72665a990; +T_2 ; + %wait E_000001d726658840; + %load/vec4 v000001d726656430_0; + %nor/r; + %flag_set/vec4 8; + %jmp/0xz T_2.0, 8; + %pushi/vec4 0, 0, 3; + %assign/vec4 v000001d7266a4530_0, 0; + %jmp T_2.1; +T_2.0 ; + %load/vec4 v000001d72665ab20_0; + %flag_set/vec4 9; + %flag_get/vec4 9; + %jmp/0 T_2.4, 9; + %load/vec4 v000001d7266a4530_0; + %cmpi/u 7, 0, 3; + %flag_get/vec4 5; + %and; +T_2.4; + %flag_set/vec4 8; + %jmp/0xz T_2.2, 8; + %load/vec4 v000001d7266a4530_0; + %addi 1, 0, 3; + %assign/vec4 v000001d7266a4530_0, 0; + %jmp T_2.3; +T_2.2 ; + %pushi/vec4 0, 0, 3; + %assign/vec4 v000001d7266a4530_0, 0; +T_2.3 ; +T_2.1 ; + %jmp T_2; + .thread T_2; + .scope S_000001d72665a990; +T_3 ; + %wait E_000001d726658840; + %load/vec4 v000001d726656430_0; + %nor/r; + %flag_set/vec4 8; + %jmp/0xz T_3.0, 8; + %pushi/vec4 0, 0, 3; + %assign/vec4 v000001d7266a45d0_0, 0; + %jmp T_3.1; +T_3.0 ; + %load/vec4 v000001d72665abc0_0; + %flag_set/vec4 9; + %flag_get/vec4 9; + %jmp/0 T_3.4, 9; + %load/vec4 v000001d7266a45d0_0; + %cmpi/u 7, 0, 3; + %flag_get/vec4 5; + %and; +T_3.4; + %flag_set/vec4 8; + %jmp/0xz T_3.2, 8; + %load/vec4 v000001d7266a45d0_0; + %addi 1, 0, 3; + %assign/vec4 v000001d7266a45d0_0, 0; + %jmp T_3.3; +T_3.2 ; + %pushi/vec4 0, 0, 3; + %assign/vec4 v000001d7266a45d0_0, 0; +T_3.3 ; +T_3.1 ; + %jmp T_3; + .thread T_3; +# The file index is used to find the file name in the following table. +:file_names 3; + "N/A"; + ""; + "ram.v"; diff --git a/ip_1_port_ram/tb_ram.v b/ip_1_port_ram/tb_ram.v index ce0867b..e349d50 100644 --- a/ip_1_port_ram/tb_ram.v +++ b/ip_1_port_ram/tb_ram.v @@ -12,62 +12,9 @@ initial begin #50 sys_rst <= 1'b1; end - -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 - - -reg [7:0]counter; // 计数到15 清零, 变化范围 0~15 -wire ram_rw; -assign ram_rw = ram_en && (counter <= 8'b111); // 计数器 分成读写各占一半时间, 0~7的时候高电平进行写, 8~15低电平进行读取 -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 - - -reg [2:0]ram_addr; // 地址变化范围 0~7就行了 -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 - - -reg [2:0]ram_data; // 假想写入的数据, 数据变化范围是0~7, 只有在 ram_rw 是写入的时候进行累加并写入地址内 -always @(posedge sys_clk or negedge sys_rst) begin - if (!sys_rst) begin - ram_data <= 3'b0; - end - // 如果是写, 并且还没到最大数 - else if (ram_rw && ram_data < 3'b111) begin - ram_data <= ram_data + 3'b1; - end - else begin - ram_data <= 3'b0; - end -end +ram u_ram( + .sys_clk(sys_clk), + .sys_rst(sys_rst) +); endmodule \ No newline at end of file diff --git a/ip_1_port_ram/配置.png b/ip_1_port_ram/配置.png new file mode 100644 index 0000000..8d1ee88 Binary files /dev/null and b/ip_1_port_ram/配置.png differ