数据通路的作用
数据在功能部件之间传送的路径称为数据通路,建立数据通路的任务是由“控制部件"来完成的
- 内部数据通路:CPU内部的数据传送通路,用于在寄存器之间或寄存器ALU之间传送数据。
- 外部数据通路:一般借助系统总线,将寄存器(MAR和MDR)与存储器和I/O模块连接起来。
- 内部总线:是指同一部件,如CPU内部连接各寄存器及运算部件之间的总线
- 系统总线:是指同一台计算机系统的各部件,如CPU、内存、通道和各类I/O接口间互相连接的总线。
一、多周期实现示例

顶层代码:
`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 **********/
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 reset = PB[0];
wire clk = PB[1];
wire [3:0] DATA = S[3:0];
wire [1:0] INDEX = S[5:4];
wire RFoe = S[6];
wire GRSoe = S[7];
wire DATAoe= S[8];
wire [3:0] ALUop = S[12:9];
// wire = S[13];
wire RFce = S[14];
wire PSWce= S[15];
wire GRSce= S[16];
wire RXce = S[17];
/************* The logic of this experiment *************/
//各模块间连线信号
wire [3:0] BUS, RX_Q, F, RF_Q, GRS_Q;
wire [3:0] FLAG, PSW_Q;
//模块实例
ALU #(4) ALU_inst(.iOp(ALUop), .iX(RX_Q), .iY(BUS), .oF(F), .oFlag(FLAG), .Cin(PSW_Q[0]));
GRS #(4) GRS_inst(.iD(BUS), .oQ (GRS_Q), .Load(GRSce), .Clk(clk), .Index(INDEX));
DataReg #(4) RX_inst(.oQ(RX_Q), .iD(BUS), .Clk(clk), .Load(RXce), .Reset(reset));
DataReg #(4) RF_inst(.oQ(RF_Q), .iD(F), .Clk(clk), .Load(RFce), .Reset(reset));
DataReg #(4) PSW_inst(.oQ(PSW_Q), .iD(FLAG), .Clk(clk), .Load(PSWce ), .Reset(reset));
//三态缓冲器逻辑描述
assign BUS = RFoe ? RF_Q : 4'bzzzz;
assign BUS = GRSoe ? GRS_Q : 4'bzzzz;
assign BUS = DATAoe ? DATA : 4'bzzzz;
/****** Internal signal assignment to output port *******/
assign L[25:22] = PSW_Q;
assign L[21:18] = FLAG;
assign HD[5] = RX_Q;
assign HD[4] = BUS;
assign HD[3] = GRS_Q;
assign HD[1] = RF_Q;
assign HD[0] = F;
endmodule
ALU
module ALU
#(parameter N=4)
(
input wire [N-1:0]iOp,
input wire Cin,
input wire [N-1:0] iX,
input wire [N-1:0] iY ,
output wire [N-1:0] oF,
output wire [N-1:0] oFlag
);
wire [N-1:0]M;
logic [N:0]result;
wire SR;
wire SV;
wire SL;
wire [1:0]SW;
wire [N-1:0] A,B;
wire C0;
always@(iOp[N-1:0])
begin
case(iOp[N-1:0]) //F=X;
4'b0000:begin
SW[1:0]=2'b00; //11
M[3:0]=4'b0000;
SV=1'b1;
SR=1'b0;
SL=1'b0;
end
4'b0001: begin //F=X+Y
SW[1:0]=2'b00;
M[3:0]=4'b0001;
SV=1'b1;
SR=1'b0;
SL=1'b0;
end
4'b0010: begin //F=X-Y
SW[1:0]=2'b00;
SV=1'b1;
M[3:0]=4'b0110;
SR=1'b0;
SL=1'b0;
end
4'b0011:begin //F=X &Y
SV=1'b1;
SW[1:0]=2'b01;
M[3:0]=4'b0001;
SR=1'b0;
SL=1'b0;
end
4'b0100:begin // F=X or Y
SV=1'b1;
SW[1:0]=2'b10;
M[3:0]=4'b0001;
SR=1'b0;
SL=1'b0;
end
4'b0101:begin //F=X ^Y
SV=1'b1;
SW[1:0]=2'b11;
M[3:0]=4'b0001;
SL=1'b0;
SR=1'b0;
end
4'b0110:begin //F=X/2
SR=1'b1;
SV=1'b0;
SL=1'b0;
SW[1:0]=2'b00;
M[3:0]=4'b0000;
end
4'b0111:begin
SL=1'b1; //F=2X
SV=1'b0;
SR=1'b0;
SW[1:0]=2'b00;
M[3:0]=4'b0000;
end
4'b1000:begin //F=!X
SV=1'b1;
SW[1:0]=2'b11;
M[3:0]=4'b0011;
SL=1'b0;
SR=1'b0;
end
4'b1001:begin //F=X+1
SV=1'b1;
M[3:0]=4'b0100;
SL=1'b0;
SR=1'b0;
SW[1:0]=2'b00;
end
4'b1010:begin //F=X-1
SV=1'b1;
M[3:0]=4'b0011;
SL=1'b0;
SR=1'b0;
SW[1:0]=2'b00;
end
4'b1011:begin //F=X+Y+Cin
SV=1'b1;
M[3:0]=4'b1001;
SL=1'b0;
SR=1'b0;
SW[1:0]=2'b00;
end
4'b1100:begin //F=X-Y-Cin
SV=1'b1;
M[3:0]=4'b1010;
SL=1'b0;
SR=1'b0;
SW[1:0]=2'b00;
end
default:begin
SV=1'b0;
M[3:0]=4'b0000;
SL=1'b0;
SR=1'b0;
SW[1:0]=2'bXX;
end
endcase
end
//assign C0 =(Cin & M[3] & M[0]| M[2]);
wire sign, zero, overflow, carryOut;
assign A[3]=SR & iX[3] | iX[3] & SV | SL &iX[2] ;
assign A[2]=SR & iX[3] | iX[2] & SV | SL &iX[1];
assign A[1]=SR & iX[2] | iX[1] & SV | SL &iX[0] ;
assign A[0]=SR & iX[1] | iX[0] & SV | SL &1'b0 ;
assign B[3] =(M[0] & iY[3]) | (M[1] & !iY[3]) ;
assign B[2] =M[0] & iY[2] | M[1] & !iY[2] ;
assign B[1] =M[0] & iY[1] | M[1] & !iY[1] ;
assign B[0] =M[0] & iY[0] | M[1] & !iY[0] ;
always_comb
begin
case({SW[1:0]})
2'b00: result=A+B+C0;
2'b01: result=iX & B;
2'b10: result=iX |B;
2'b11: result=iX ^ B;
default:begin
if(SV==0 & SR==0 & SL==0)
result={(5){1'bZ}};
end
endcase
end
assign carryOut=result[4];
assign oF[3:0] = result[3:0];
assign sign = oF[3];
always@( SV,SR,SL)
begin
if(SV==0 & SR==0 & SL==0)
zero=0;
else
zero = (oF==0) ? 1 : 0; // ~|F;
end
assign overflow = (~A[3]) & ~B[3] & oF[3] | (A[3]) & B[3] & ~oF[3] ;
assign oFlag={sign, zero, overflow, carryOut};
endmodule
GRS
module GRS
#(parameter N = 4)
(
input wire [N-1:0]iD,
input wire Load,
input wire[1:0]Index,
input wire Clk,
output wire[N-1:0]oQ
);
// 2-4 decode 二四译码器
logic load3, load2, load1, load0;
always_comb begin
if (Load)
case (Index)
2'b00: {load3, load2, load1, load0} = 4'b0001;
2'b01: {load3, load2, load1, load0} = 4'b0010;
2'b10: {load3, load2, load1, load0} = 4'b0100;
2'b11: {load3, load2, load1, load0} = 4'b1000;
default: {load3, load2, load1, load0} = 4'bx;
endcase
else
{load3, load2, load1, load0} = 4'b0000;
end
// register instantiation 译码器的实例化
logic [N-1:0] R0_Q, R1_Q, R2_Q, R3_Q;
DataReg #(N) R0(.oQ(R0_Q), .iD(iD), .Clk(Clk), .Load(load0), .Reset(1'b0));//由于本实验没有用到复位信号,所以reset恒为0,在待会的三端口寄存器堆里可以将第一个寄存器的信号设置为1使它无法存值
DataReg #(N) R1(.oQ(R1_Q), .iD(iD), .Clk(Clk), .Load(load1), .Reset(1'b0));
DataReg #(N) R2(.oQ(R2_Q), .iD(iD), .Clk(Clk), .Load(load2), .Reset(1'b0));
DataReg #(N) R3(.oQ(R3_Q), .iD(iD), .Clk(Clk), .Load(load3), .Reset(1'b0));
// 4-1 MUX 四选一多路器
always_comb begin
case (Index)//根据地址信号选择输出哪个寄存器的值
2'b00: oQ = R0_Q;
2'b01: oQ = R1_Q;
2'b10: oQ = R2_Q;
2'b11: oQ = R3_Q;
endcase
end
/****** Internal signal assignment to output port *******/
endmodule
二、单周期实现示例

视频演示
顶层代码:
`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 **********/
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 reset = PB[0];
wire clk = PB[1];
wire [1:0] WINDEX = S[5:4];
wire RFoe = S[6];
wire [1:0]SW =S[13:12];
wire M0 = S[14];
wire [3:0] enter=S[11:8];
wire[1:0]RA1=S[1:0];
wire [1:0]RA2=S[3:2];
wire choose =S[7];
/************* The logic of this experiment *************/
//各模块间连线信号
wire [3:0] tempmux, F, GRS_Q1,GRS_Q2;
wire [3:0] FLAG;
assign tempmux = choose? enter:GRS_Q2 ;
//模块实例
ALU #(4) ALU_inst(.iX(GRS_Q1), .iY(tempmux), .oF(F), .oFlag(FLAG), .M0(M0),.SW(SW));
GRS #(4) GRS_inst(.iD(F),.Load(RFoe),.WIndex(WINDEX),.RIndex1(RA1),.RIndex2(RA2),.Clk(clk),.oQ1 (GRS_Q1), .oQ2(GRS_Q2));
/****** Internal signal assignment to output port *******/
assign L[21:18] = FLAG;
assign HD[1] = GRS_Q1;
assign HD[2] = GRS_Q2;
assign HD[0] = tempmux;
assign HD[3] = F;
endmodule
GRS模块
module GRS
#(parameter N = 4)
(
input wire [N-1:0]iD,
input wire Load,
input wire[1:0]WIndex,
input wire [1:0]RIndex1,
input wire [1:0]RIndex2,
input wire Clk,
output wire[N-1:0]oQ1,
output wire [N-1:0]oQ2
);
// 2-4 decode
logic load3, load2, load1, load0;
always_comb begin
if (Load)
case (WIndex)
2'b00: {load3, load2, load1, load0} = 4'b0001;
2'b01: {load3, load2, load1, load0} = 4'b0010;
2'b10: {load3, load2, load1, load0} = 4'b0100;
2'b11: {load3, load2, load1, load0} = 4'b1000;
default: {load3, load2, load1, load0} = 4'bx;
endcase
else
{load3, load2, load1, load0} = 4'b0000;
end
// register instantiation
logic [N-1:0] R0_Q, R1_Q, R2_Q, R3_Q;
DataReg #(N) R0(.oQ(R0_Q), .iD(iD), .Clk(Clk), .Load(load0), .Reset(1'b1));//这个reset改了
DataReg #(N) R1(.oQ(R1_Q), .iD(iD), .Clk(Clk), .Load(load1), .Reset(1'b0));
DataReg #(N) R2(.oQ(R2_Q), .iD(iD), .Clk(Clk), .Load(load2), .Reset(1'b0));
DataReg #(N) R3(.oQ(R3_Q), .iD(iD), .Clk(Clk), .Load(load3), .Reset(1'b0));
// 4-1 MUX 现在有两个多路器
logic [N-1:0] GRS_Q1, GRS_Q2;
always_comb begin
case (RIndex1)
2'b00: oQ1 = R0_Q;
2'b01: oQ1 = R1_Q;
2'b10: oQ1 = R2_Q;
2'b11: oQ1 = R3_Q;
endcase
case (RIndex2)
2'b00: oQ2 = R0_Q;
2'b01: oQ2 = R1_Q;
2'b10: oQ2 = R2_Q;
2'b11: oQ2 = R3_Q;
endcase
end
endmodule
ALU模块
module ALU
#(parameter N=4)
(
input wire [N-1:0] iX,
input wire [N-1:0] iY ,
input wire [1:0]SW,
input wire M0,
output wire [N-1:0] oF,
output wire [N-1:0] oFlag
);
logic [N:0]result;
wire [N-1:0] A,B;
wire C0;
assign C0=M0;
wire sign, zero, overflow, carryOut;
assign A=iX;
assign B=iY ;
always_comb
begin
case({SW[1:0]})
2'b00: result=A+B^M0+C0;
2'b01: result=A & B;
2'b10: result=A|B;
2'b11: result=A ^ B;
default:result={(N+1){1'bx}};
endcase
end
assign carryOut = result[N];
assign oF[N-1:0] = result[N-1:0];
assign sign = oF[N-1];
assign overflow = (~A[N-1]) & ~B[N-1] & oF[N-1] | (A[N-1]) & B[N-1] & ~oF[N-1] ;
assign oFlag={sign, zero, overflow, carryOut};
endmodule
公用模块
七段数码管显示模块
module SevenSegDecode(
input logic[3:0]iData,
output logic[7:0]oSeg
);
always_comb
begin
case(iData)
4'h0:oSeg=8'b11000000;
4'h1:oSeg=8'b11111001;
4'h2:oSeg=8'b10100100;
4'h3:oSeg=8'b10110000;
4'h4:oSeg=8'b10011001;
4'h5:oSeg=8'b10010010;
4'h6:oSeg=8'b10000010;
4'h7:oSeg=8'b11111000;
4'h8:oSeg=8'b10000000;
4'h9:oSeg=8'b10010000;
4'hA:oSeg=8'b10001000;
4'hB:oSeg=8'b10000011;
4'hC:oSeg=8'b11000110;
4'hD:oSeg=8'b10100001;
4'hE:oSeg=8'b10000110;
4'hF:oSeg=8'b10001110;
default:oSeg=8'bx;
endcase
end
endmodule
寄存器
module DataReg
#(parameter N = 4)
( output reg [N-1:0] oQ,
input wire [N-1:0] iD,
input wire Clk,
input wire Load,
input wire Reset
);
always @(posedge Clk or posedge Reset)
begin
if (Reset)
oQ <= 0;
else if (Load)
oQ <= iD;
end
endmodule
版权声明:本文为weixin_46831482原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。