1. 一个32组位宽为32的寄存器堆
- 框图
-
代码
- regfile.h
`ifndef __FEGFILE_HEADER__`define __REGFILE_HEADER__`define HIGH 1'b1`define LOW 1'b0`define ENABLE_ 1'b0`define DISABLE_ 1'b1`define DATA_W 32`define DataBus 31:0`define DATA_D 32`define ADDR_W 5`define AddrBus 4:0`endif
- regfile.v
`include "regfile2.h"module regfile2 (input wire clk,input wire reset_,input wire [`AddrBus] addr,input wire [`DataBus] d_in,input wire we_,output wire [`DataBus] d_out);reg [`DataBus] ff [`DATA_D-1:0]; //寄存器序列integer i;assign d_out = ff[addr];always @(posedge clk or negedge reset_) beginif (reset_ == `ENABLE_) beginfor (i = 0;i < `DATA_D;i = i + 1) beginff[i] <= #1{`DATA_W{1'b0}};endend else beginif (we_ == `ENABLE_) beginff[addr] <= #1 d_in;endendendendmodule
2. ALU
module alu(input [2:0] a,b,input [1:0] sel,output reg [3:0] out
)always @(a,b,sel) begincase(sel)2'b00: out = a+b;2'b01: out = ~(a+b);2'b10: out = a<<1;2'b11: out = ~a;default:out = 4'b0000;endcaseend
endmodule
3. 同步使能,异步复位的D触发器
module Dff (input clk,input clr,input en,input D,output reg q,output qb
);assign qb = ~q;always @(posedge clk or posedge clr) beginif (clr) q <= 0;//异步复位else if (en) q <= D;//同步使能end
endmodule
这个Verilog模块实现了一个带有异步复位功能的D触发器。在这个模块中,异步复位由输入信号clr
控制。
异步复位的实现方式是,当clr
信号为高电平(假定高电平表示复位时),触发器的输出q
将被强制置为逻辑0,无论时钟信号clk
和使能信号en
的状态如何。这意味着,无论何时clr
信号变为高电平,都会立即将q
复位为0。
以下是对代码的解释:
-
assign qb = ~q;
行将qb
定义为q
的反相信号,即qb
始终是q
的逻辑反值。 -
always @(posedge clk or posedge clr) begin
声明一个始终块,该块在时钟上升沿(posedge clk
)或异步复位上升沿(posedge clr
)时触发。 -
if (clr) q <= 0;
行检查clr
信号的状态。如果clr
为高电平(即异步复位条件触发),则q
被赋值为0,实现了异步复位。 -
else if (en) q <= D;
行在没有异步复位的情况下,检查使能信号en
。如果en
为高电平,那么q
将被赋值为输入信号D
,实现了同步使能。
这个模块的功能是,当clr
信号为高电平时,无论何时都会将q
置为0,而当clr
信号为低电平且en
信号为高电平时,q
会根据输入信号D
的值来更新。这使得在需要时可以通过异步复位来立即清除触发器的状态。
4. 移位寄存器
module shift_reg (input clk,input rst,input data_in,output reg [7:0] q
);always @(posedge clk) beginif (rst) q <= 0;else begin q[7:1] <= q[6:0];q[0] <= data_in;endendendmodule
5. 使用6个D触发器实现一个6位的寄存器
module DFlipFlop (input clk,input clr_n, // 异步复位信号,低电平有效input D,output reg Q
);always @(posedge clk or negedge clr_n) beginif (!clr_n)Q <= 1'b0; // 异步复位时,输出清零elseQ <= D; // 非复位时,将输入数据加载到输出endendmodulemodule SixBitRegister (input clk,input clr_n,input [5:0] data_input,output [5:0] data_output
);reg [5:0] q; // 6位寄存器的输出integer i;always @(posedge clk or negedge clr_n) beginif (!clr_n)q <= 6'b0; // 异步复位时,全部位清零elsefor (i = 0; i < 6; i = i + 1)DFlipFlop dff (.clk(clk),.clr_n(clr_n),.D(data_input[i]),.Q(q[i])); // 使用循环实例化六个D触发器endassign data_output = q;endmodule
6. 按键产生时钟脉冲,移位寄存器
module shift_reg (input btn, // 按键输入,用于产生时钟脉冲output reg clk_pulse, // 时钟脉冲信号input rst,input data_in,output reg [7:0] q
);reg clk_edge = 0;always @(posedge btn) beginclk_edge <= ~clk_edge; // 按键按下时切换时钟边沿endalways @(posedge clk_edge or posedge rst) beginif (rst)q <= 8'b0;elsebeginq[7:1] <= q[6:0];q[0] <= data_in;endend// 产生时钟脉冲always @(posedge clk_edge) beginclk_pulse <= 1'b1;endendmodule
7. 串入并出74SL64芯片
module ShiftRegister_74LS164 (input clk, // 时钟输入input srclr, // 异步复位输入input serial_in, // 串行输入output [7:0] parallel_out // 并行输出
);reg [7:0] shift_register; // 移位寄存器存储器件always @(posedge clk or posedge srclr) beginif (srclr)shift_register <= 8'b0; // 异步复位时,寄存器清零elseshift_register <= {shift_register[6:0], serial_in}; // 数据移位endassign parallel_out = shift_register; // 并行输出与寄存器值关联endmodule
8.同步使能、异步清零的16进制计数器
module counter_16(input clk,input clr,input en,output reg [3:0] q
);always @(posedge clk or posedge clr) beginif (q <= 0) q <= 0;else if (en) q <= q + 1;end
endmodule
//激励关键代码
initial forkckl = 0;clr = 0;en = 0;forever begin#10 clk = ~clk;#25 clr = 1;#55 clr = 0;#35 en = 1;end
join
上面的Verilog代码片段展示了一个 initial
块内的 fork-join
结构,该结构用于并发地控制信号 clk
、clr
和 en
的变化。以下是对这段代码的详细解释:
-
fork
和join
:fork
和join
是一对用于创建并发代码块的关键字。fork
标志着代码分支的开始,允许同时执行多个线程。join
表示所有分支线程都执行完毕后再继续执行后续的代码。在这个例子中,fork
启动了一个并发线程,而join
用于结束这个线程。 -
initial
块:initial
块是Verilog中用于模拟和初始化的代码块。在仿真开始时执行其中的代码。 -
初始化信号:在
initial
块的开头,clk
、clr
、和en
这三个信号都被初始化。它们的初始值分别是 0。 -
forever
循环:forever
关键字用于创建一个无限循环,表示其中的代码将一直执行下去。 -
#10
、#25
、#55
、#35
:这些是时间延迟操作符,用于指定等待的时间。#10
表示等待 10 个时间单位,#25
表示等待 25 个时间单位,以此类推。 -
时钟信号
clk
的翻转:#10 clk = ~clk;
表示在等待 10 个时间单位后,翻转时钟信号clk
的状态,从 0 到 1 或从 1 到 0。这模拟了时钟的周期性振荡。 -
异步复位信号
clr
的设置和清除:#25 clr = 1;
表示在等待 25 个时间单位后,将异步复位信号clr
设置为 1,表示触发异步复位。然后#55 clr = 0;
表示在等待 55 个时间单位后,将clr
再次设置为 0,表示清除异步复位。 -
使能信号
en
的设置和清除:#35 en = 1;
表示在等待 35 个时间单位后,将使能信号en
设置为 1,表示启用某些操作。请注意,en
之后没有清除,因此在整个仿真期间都会保持为 1。
9. 偶数分频
采用加法计数的方法,知识要对时钟的上升沿进行计数,因为输出波形的改变仅仅发生在时钟上升沿。
module divf_even (input clk,output reg clk_N
);
parameter N = 6;
integer p;
always @(posedge clk) beginif (p == N/2-1) beginp = 0;clk_N = ~clk_N;endelse p = p + 1;
end
endmodule
10. 奇数分频
奇数分频——错位异或法。对于实现占空比为50%的N倍奇数分频,首先进行上升沿出发的模N计数计数到一选定值时进行输出时钟翻转,得到一个占空比为50%的N分频时钟clk1;然后在下降沿,经过与上面选定时刻相差(N-1)/2时刻,反转另一个时钟,这样得到另一个占空比为50%的N分频时钟clk2.将clk1和clk2两个时钟进行异或运算,就得到了占空比为50%的奇数分频时钟。利用了相位差
module divf_oddn(input clk,output clk_N
);parameter N = 3;integer p = 0;reg clk_p = 0,clk_q = 0;always @(posedge clk) beginif (p == N-1) p <= 0;else p <= p + 1;endalways @(posedge clk) beginif (p == N - 1) clk_p <= ~clk_p;endalways @(negedge clk) beginif (p == (N-1)/2) clk_q <= ~clk_q;endassign clk_N = clk_p ^ clk_q;
endmodule
11. 2 n 2^n 2n 分频
module divf_2pown (input clk,input rst,output clk2,output clk4,output clk8,output clk16
);reg [3:0] count;always @(posedge clk) beginif (rst) begincount <= 0;end else begincount <= count + 1;endendassign clk2 = count[0];assign clk4 = count[1];assign clk8 = count[2];assign clk16 = count[3];endmodule
12. 秒计数器
- 1s实现加1计数,计到59后再从零计数
- 同步清零,用拨码开关控制同步清零,led灯显示
top 模块
module second_top (clk,bmkg0,led
);
input clk;
input bmkg0;
output [7:0] led;
wire [7:0] sec;
wire clk_1HZ;second_divf U1(.clk_50MHZ(clk),.clk_1HZ(clk_1HZ));second U2(.clk_1HZ(clk_1HZ),.clr(bmkg0),sec(sec));second_disp U3(.sec(sec),.q(led));
endmodule
分频模块 50MHz–> 1Hz
module second_divf (clk_50MHZ,clk_1HZ
);input clk_50MHZ;output reg clk_1HZ;reg [25:0] cnt;always @(posedge clk_50MHZ) beginif (cnt == 25000000-1) beginclk_1HZ = ~clk_1HZ;cnt <= 0;end else begincnt = cnt + 1;endend
endmodule
计数模块
module second(clk_1HZ,clr,sec
);input clk_1HZ;input clr;output reg [7:0] sec;always @(posedge clk_1HZ or posedge clr) beginif (clr) beginsec <= 0;end else if (sec == 59) sec <= 0;else sec <= sec + 1;end
endmodule
显示模块
module second_disp (sec,q
);input [7:0] sec;output [7:0] q;assign q = sec;
endmodule
13. 序列检测器
再连续信号中,检测是否包含“110”序列,当包含该序列时,指示灯就亮,否则指示灯灭。
顶层模块
module SerialTect_top (clk,key,led
);input clk;input [1:0] key;output led;wire pulse;wire [1:0] key_debounce;IP_smg_divf U1(.clk_50MHz(clk),.clk_190Hz(clk_190Hz));IP_key_debounce U2(.key_debounce(key_debounce[0]),.clk_190Hz(clk_190Hz),.key0(key[1]));IP_pulse_gen U4(.clk(clk),.key(|key_bounce),.pulse(pulse));Serial_compare U5(.clk(pulse),.serialData(key_debounce[1]),.result(led));
endmodule
分频模块
按键消抖模块
脉冲信号模块
序列检测模块
module Serial_compare (clk,serialData,result
);input clk;input serialData;output result;parameter s0 = 2'b00,s1 = 2'b01,s2 = 2'b10,s3 = 2'b11;reg [1:0] next_st = s0;always @(posedge clk) begincase (next_st)s0: if (serialData == 1'b1) next_st = s1;else next_st = s0;s1: if (serialData == 1'b1) next_st = s2;else next_st = s0;s2: if (serialData == 1'b1) next_st = s2;else next_st = s3;s3: if (serialData == 1'b1) next_st = s1;else next_st = s0;default: next_st = s0;endcaseendassign result = (next_st == s3)?1:0;endmodule
14. 简易处理器设计
1. 设计要求
- 完成处理器指令集的设计
- 完成处理器的设计,要求能够识别处理指令集中的任何指令
- 设计一段程序,要求该段程序用到指令集中的所有指令,并通过处理器运行这段程序得到结果
2. 设计
- 处理器的组成结构
- 简易处理器的功能
完成 2*(0+1+2+…+10)=?
- 指令系统的设计
- 寄存器传输指令
- 装在指令
- 算术运算指令:完成加减运算
- 逻辑移位指令:完成左移操作
- 存储指令
- 分支指令
所有的指令都包含4位操作码和12位操作数
汇编语言描述
机器码描述
3. 设计实现
3.1 顶层设计
- CPU顶层测试模块
module cpu_mem_test (clk,rst,key,duan,wei
);input clk,rst;input [1:0] key;output [7:0] duan;output [3:0] wei;wire [39:0] rf_data;wire start;wire [7:0] PC;wire [15:0] IR;cpu_mem cpu_mem(.clk(clk),.rst(rst),.start(start),.rf_data(rf_data),.PC(PC),.IR(IF));fpag_step_ctrl step_ctrl(.clk(clk),.rst(rst),.key(key),.start(start),.duan(duan),.wei(wei),.PC(PC),.IR(IR),.rf_data(rf_data)) ;
endmodule
- 含ROM和RAM的CPU设计
module cpu_mem (clk,rst,start,rf_data,PC,IR
);input clk,rst;input start;output [39:0] rf_data;output [7:0] PC;output [15:0] IR;wire ROM_en;wire [15:0] IR; wire wr_ram,cs_ram;wire [7:0] addr_ram;wire [7:0] alu_out;wire clk_n;assign clk_n = ~clk;cpu cpu(.clk(clk),.rst(rst),.start(start),.ROM_en(ROM_en),.IR(IR),.PC(PC),.rf_data(rf_data),.wr_ram(wr_ram),.cs_ram(cs_ram),.addr_ram(addr_ram),.alu_out(alu_out));rom rom_instruction(.clk(clk_n),.rst(rst),.rd(ROM_en),.rom_data(IR),.rom_addr(PC));ram ram_data(.clk(clk_n),.wr(wr_ram),.cs(cs_ram),.addr(addr_ram),.datain(alu_out));
endmodule
- 将CPU进一步规划成datapath和controller
- cpu 内部模块划分——包括数据路径和控制器
module cpu (clk,rst,start,ROM_en,IR,PC,rf_data,wr_ram,cs_ram,addr_ram,alu_out
);input clk,rst;input start;input [15:0] IR;output [7:0] PC;output ROM_en;output wr_ram,cs_ram;output [7:0] addr_ram;output [7:0] alu_oout;output [39:0] rf_data;wire [7:0] imm;wire [3:0] sel_rf;wire [2:0] sel_alu;wire sel_mux;wire r_wf,en_rf,en_reg,en_alu,en_imm,alu_zero;wire clk_n;assign clk_n = ~clk;dp datapath(.rst(rst),.clk(clk_n),.r_wf(r_wf),.en_rf(en_rf),.en_reg(en_reg),.en_alu(en_alu),.en_imm(en_imm),.sel_rf(sel_rf),.sel_alu(sel_alu),.sel_mux(sel_mux),.imm(imm),.alu_zero(alu_zero),.alu_out(alu_out),.rf_data(rf_data));ctrl controller(.rst(rst),.start(start),.clk(clk),.alu_zero(alu_zero),.r_wf(r_wf),.en_rf(en_rf),.en_reg(en_reg),.en_alu(en_alu),.en_imm(en_imm),.sel_rf(sel_rf),.sel_alu(sel_alu),.sel_mux(sel_mux),.imm(imm),.PC(PC),.IR(IR),.ROM_en(ROM_en),.wr_ram(wr_ram),.cs_ram(cs_ram),.addr_ram(addr_ram));
endmodule
- 数据路径部分细分框图
- 数据路径顶层文件
module dp(rst,clk,r_wf,en_rf,en_reg,en_alu,en_imm,sel_rf,sel_alu,sel_mux,imm,alu_zero,alu_out,rf_data
);input rst,clk,r_wf,en_rf,en_reg,en_alu,en_imm;input [7:0] imm;input [2:0] sel_alu;input [3:0] sel_rf;input sel_mux;output alu_zero;output [39:0] rf_data;output [7:0] alu_out;wire [7:0] op1,op2,out_imm,out_rf;register register0(.clk(clk),.en(en_reg),.in(op1),.out(op2)) ;register register1(.clk(clk),.en(en_imm),.in(imm),.out(out_imm));mux21 mux0(.sel(sel_mux),.in1(out_imm),.in2(out_rf),.out(op1));alu alu0(.clk(clk),.en(en_alu),.sel(sel_alu),.in1(op1),.in2(op2),.out(alu_out),.alu_zero(alu_zero));rf rf0(.rst(rst),.clk(clk),.r_w(r_wf),.enb(en_rf),.in(alu_out),.sel(sel_rf),.out(out_rf),.rf_data(rf_data));
endmodule
3.2 基本部件设计
- ALU
module alu (clk,en,sel,in1,in2,out,alu_zero;
);input en,clk;input [2:0] sel;input [7:0] in1,in2;output reg[7:0]out;output reg alu_zero;always @(posedge clk) beginif (en) case(sel)3'b000: out = in1;3'b001: if (in1 == 0) alu_zero = 1;else alu_zero = 0;3'b010: out = in1 + in2;3'b011: out = in1 - in2;3'b100: out = in1<<in2;default: ;endcase end
endmodule
- 异步使能寄存器
module register (clk,en,in,out
);input clk,en;input [7:0] in;output reg[7:0] out;reg [7:0] val;always @(posedge clk)val <= in;always @(en,val) beginif (en == 1'b1) out <= val;else ;end
endmodule
- 通用寄存器
module rf (rst,clk,r_w,enb,in,sel,out,rf_data
);input rst,clk,enb,r_w;input [7:0] in;input [3:0] sel;output reg[7:0]out;output [39:0] rf_data;reg [7:0] reg_file[0:15];integer i;assign rf_data = {reg_file[4],reg_file[3],reg_file[2],reg_file[1],reg_file[0]};always @(posedge rst or posedge clk) beginif (rst) beginfor (i = 0;i < 15;i = i + 1)reg_file[i] <= 0; end else if (enb == 1) beginif (r_w == 0) reg_file[sel] <= in;else out <= reg_file[sel];endend
endmodule
- 二选一多路选择器
module mux21 (sel,in1,in2,out
);input sel;input [7:0] in1,in2;output[7:0] out;assign out = (sel)?in2:in1;
endmodule
- 控制器
控制器提供必要的控制信号,使得数据流通过数据路径后达到预期的功能。控制器部分使用状态机计数来实现,这个状态机根据当前的状态和输入的信号值,输出更新后的状态和相应的控制信号。
module ctrl (rst,start,clk,alu_zero,r_wf,en_rf,en_reg,en_alu,en_imm,sel_rf,sel_alu,sel_mux,imm,PC,IF,ROM_en,wr_ram,cs_ram,addr_ram
);input rst,start,clk;input alu_zero;input [15:0] IR;output reg r_wf,en_rf,en_reg,en_alu,en_imm;output reg[3:0]sel_rf;output reg[2:0]sel_alu;output reg sel_mux;output reg[7:0]imm,PC;output reg ROM_en;output reg wr_ram,cs_ram;output reg[7:0]addr_ram;parameter s0 = 6'b000000,s1 = 6'b000001,s2 = 6'b000010,s3 = 6'b000011,s4 = 6'b000100,s5 = 6'b000101,s5_2 = 6'b000110,s5_3 = 6'b000111,s6 = 6'b001000,s6_2 = 6'b001001,s6_3 = 6'b001010,s6_4 = 6'b001000,s6_5 = 6'b001100,s7 = 6'b001101,s7_2 = 6'b001110,s7_3 = 6'b001111,s7_4 = 6'b010000,s7_5 = 6'b010001,s8 = 6'b010010,s8_2 = 6'b010011,s8_3 = 6'b010100,s9 = 6'b010101,s9_2 = 6'b010110,s9_3 = 6'b010111,s10 = 6'b100000,s10_2 = 6'b100001,s10_3 = 6'b100010,s11 = 6'b100011,s11_2 = 6'b100100,s11_3 = 6'b100101,s11_4 = 6'b100110,s11_5 = 6'b100111,s12 = 6'b101000,done = 6'b101001;reg [5:0] state;parameter loadi = 4'b0011,add = 4'b0100,sub = 4'b0101,jz = 4'b0110,store = 4'b1000,shiftL = 4'b0111,reg2reg = 4'b0010,halt = 4'b1111;reg [3:0] OPCODE;reg [7:0] address;reg [3:0] register;always @(posedge rst or posedge clk) beginsel_mux <= 1'b1;en_rf <= 1'b0;en_reg <= 1'b0;en_alu <= 1'b0;en_imm <= 1'b0;ROM_en <= 1'b0;wr_ram <= 1'b0;cs_ram <= 1'b0;addr_ram <= 0;if (rst) beginstate <= s0;PC <= 0;end else begincase (state)s0: beginPC <= 0;state <= s1;end s1: beginif (start == 1'b1) beginROM_en <= 1;state <= s2;endelse state <= s1;ends2: beginOPCODE <= IR[15:12];register <= IR[11:8];address <= IR[7:0];state <= s3;ends3: beginPC <= PC + 8'b1;state <= s4;ends4: begincase (OPCODE) loadi: state <= s5;add: state <= s6;sub: state <= s7;jz: state <= s8;store: state <= s9;reg2reg:state <= s10;shiftL: state <= s11;halt: state <= done;default:state <= s1;endcaseends5: beginimm <= address;en_imm <= 1;state <= s5_2;ends5_2:beginsel_mux <= 0;en_alu <= 1;sel_alu <= 3'b000;state <= s5_3;ends5_3:beginen_rf <= 1;r_wf <= 0;sel_rf <= register;state <= s12;ends6:beginsel_rf <= IR[7:4];en_rf <= 1;r_wf <= 1;state <= s6_2;ends6_2:beginen_reg <= 1;state <= s6_3;ends6_3:beginsel_rf <= register;en_rf <= 1;r_wf <= 1;state <= s6_4;ends6_4:beginen_alu <= 1;sel_alu <= 3'b010;state <= s6_5;ends6_5:beginsel_rf <= register;en_rf <= 1;r_wf <= 0;state <= s12;ends7: beginsel_rf <= IF[7:4];en_rf <=1;r_wf <= 1;state <= s7_2;ends7_2: beginen_reg <= 1;state <= s7_3;ends7_3: beginsel_rf <= register;en_rf <= 1;r_wf <= 1;state <= s7_4;ends7_5: beginsel_rf <= register;en_rf <= 1;r_wf <= 0;state <= s12;ends8: beginen_rf <= 1;r_wf <= 1;sel_rf <= register;state <= s8_2;ends8_2: beginen_rf <= 1;sel_alu <= 3'b001;state <= s8_3;ends8_3: beginif (alu_zero == 1) PC <= address;state <= s12; ends9: beginsel_rf <= register;en_rf <= 1;r_wf <= 1;state <= s9_2;ends9_2: beginen_alu <= 1;sel_alu <= 3'b000;state <= s9_3;ends9_3: begincs_ram <= 1;wr_ram <= 1;addr_ram <= address;state <= s12;ends10: beginsel_rf <= IR[7:4];en_rf <= 1;r_wf <= 1;state <= s10_2;ends10_2: beginen_alu <= 1;sel_alu <= 3'b000;state <= s10_3;ends10_3:beginsel_rf <= register;en_rf <= 1;r_wf <= 0;state <= s12;ends11: beginimm <= address;en_imm <= 1;state <= s11_2;ends11_2: beginsel_mux <= 0;en_reg <= 1;state <= s11_3;ends11_3: beginsel_rf <= register;en_rf <= 1;r_wf <= 1;state <= s11_4;ends11_4: beginen_alu <= 1;sel_alu <= 3'b100;state <= s11_5;ends11_5: beginsel_rf <= register;en_rf <= 1;r_wf <= 0;state <= s12;ends12: state <= s1;done: state <= done;default:;endcaseendend
endmodule
- 程序存储器
module rom (clk,rst,rd,rom_data,rom_addr
);parameter M = 16,N = 8;input clk,rst,rd;input [N-1:0] rom_addr;output reg[M-1:0] rom_data;reg [M-1:0] memory[0:2**N-1];always @(posedge clk or posedge rst) beginif (rst) begin:initinteger i;memory[0]=16'b0011_0000 00000000;//MOV RO,#0;memory[1]=16'b0011_0001 00001010;//MOV R1,#10;memory[2]=16'b0011_0010_00000001;//MOV R2,#1;memory[3]=16'b0011 0011 00000000;//MOV R3,#0;memory[4]=16'b0110_0001 00001000;//JZ R1,NEXT;memory[5]=16'b0100_0000_00010000;//ADD R0,R1;memory[6]=16'b0101 0001 00100000;//SUB R1,R2;memory[7]=16'b0110_0011 00000100;//JZ R3,Lo0pmemory[8]=16'b0010_0100_00000000;//MOV R4,R0memory[9]=16'b0111_0100_00000001;//RLR4,#1memory[10]=16'b1000_0100_00001010;//MOV 10H,R4memory[11J=16'b11110000 00001011;//haltfor(i=12;i<(2**N);i=i+1)//存储器其余地址存放0memory[i] = 0;end else begin:readif (rf) rom_data = memory[rom_addr];endend
endmodule
- 数据存储器
module ram (clk,rd,wf,cs,addr,datain,dataout
);parameter M = 8,N = 8;input rd,wr,cs,clk;input [N-1:0]addr;input [M-1:0]datain;output reg[M-1:0] dataout;reg [M-1:0] memory [0:2**N-1];always @(posedge clk) begin:p0if(cs) if (rd) dataout <= memory[addr];else if (wr) memory[addr] <= datain;else dataout <= 'bz;end
endmodule
4. 上Vivado
跑出来了,不知道对不对