📄 datapath.v
字号:
/*
** DATAPATH
**
** VERSION 2
**
** This core adheres to GNU Public Licence
** Jeung Joon Lee *** www.cmosexod.com
** joon.lee@quantum.com
**
** JJL 12/12/98
** updated 3/16/2000
**
**
*/
`include "inc.h"
`timescale 1 ns / 100 ps
module datapath(// system connection
sys_clk,
sys_rst_l,
// to/from sequencer
load_accH, // accumulator write signal, active low
load_axH, // AX regster write signal, active low
load_bxH, // BX " " "
//`ifdef use_reg_port
// load_portH, // PORT " " "
//`endif
load_flagH, // FLAG " " "
bbus_mux, // bbus mux selector
alu_func,
flag_mux,
reg_flag,
c_bus,
use_carry,
use_carry_add,
// to/from buscon
d_bus,
reg_pc,
// debug
b_bus,
reg_acc,
reg_ax,
reg_bx,
//`ifdef use_reg_port
// reg_port,
//`endif
flagsIN
);
// system connection
input sys_clk;
input sys_rst_l;
// to/from sequencer
input load_accH;
input load_axH;
input load_bxH;
`ifdef use_reg_port
input load_portH;
`endif
input load_flagH;
input [3:0] alu_func;
input [2:0] bbus_mux;
output [7:0] c_bus;
input use_carry;
input use_carry_add;
// to/from buscon
input [`AW-1:0] d_bus;
input [`AW-1:0] reg_pc;
// debug
output [7:0] b_bus;
output [2:0] reg_flag;
input flag_mux;
output [7:0] reg_acc;
output [7:0] reg_ax;
output [7:0] reg_bx;
`ifdef use_reg_port
output [7:0] reg_port;
`endif
output [2:0] flagsIN;
// ********************************************
//
// MEMORY ELEMENT DEFINITION
//
// ********************************************
reg [7:0] reg_ax;
reg [7:0] reg_bx;
reg [7:0] reg_acc;
`ifdef use_reg_port
reg [7:0] reg_port;
`endif
reg cout;
reg [7:0] b_bus,c_bus;
reg [2:0] flag_mux_out;
reg [2:0] reg_flag;
reg [9:0] c_temp;
wire [7:0] data;
wire flag_P;
wire flag_Z;
wire flag_C;
wire [2:0] flagsIN;
wire shifted_carry;
wire [7:0] b_bus_mux;
wire subtract;
wire carry_in;
//
// REGISTER FILE
//
// There are total of 4 registers:
// ACC accumulator 8 bit
// AX general purpose register 8 bit
// BX general purpose register 8 bit
// P I/O port register 8 bit
//
always @(posedge sys_clk or negedge sys_rst_l)
if (~sys_rst_l) begin
reg_acc <= 8'h00;
reg_ax <= 8'h00;
reg_bx <= 8'h00;
`ifdef use_reg_port
reg_port<= 8'h00;
`endif
end
else begin
if (load_accH) reg_acc <= c_bus;
if (load_axH) reg_ax <= c_bus;
if (load_bxH) reg_bx <= c_bus;
`ifdef use_reg_port
if (load_portH)reg_port<= c_bus;
`endif
end
//
// A L U
//
// This ALU provides 9 funtions:
// 0 c = a+b
// 1 c = a-b (a+~b+1)
// 2 c = a&b
// 3 c = a|b
// 4 c = a^b
// 5 c = ~a
// 6 c = a >> 1
// 7 c = a << 1
// 8 c = b
// 9 c = a
// else c = x
//
assign shifted_carry = use_carry & reg_flag[2];
// b_bus_mux = -b_bus if alu_func[0] is high
assign subtract = alu_func[0];
assign carry_in = subtract | (use_carry_add & reg_flag[2]);
assign b_bus_mux ={8{subtract}} ^ b_bus;
always @(reg_acc or b_bus or alu_func or shifted_carry or
b_bus_mux or carry_in or subtract
)
begin
// default
cout = 1'b0;
case (alu_func)
4'b0000,
4'b0001 :
// This does two's complement addition:
// {carry,c_temp[7:0]} = a[7:0] + ~b[7:0] + 1
// c_temp[8:0] = {0,a[7:0],subtract} + {subtract,b[7:0]^subtract,subtract}
begin
c_temp = ( {1'b0,reg_acc,carry_in} + {subtract,b_bus_mux,carry_in} );
c_bus = c_temp[8:1];
cout = c_temp[9];
end
4'b0010: c_bus = reg_acc&b_bus;
4'b0011: c_bus = reg_acc|b_bus;
4'b0100: c_bus = reg_acc^b_bus;
4'b0101: c_bus = ~reg_acc;
4'b0110: begin
c_bus = {shifted_carry,reg_acc[7:1]};
cout =reg_acc[0];
end
4'b0111: begin
c_bus = {reg_acc[6:0],shifted_carry};
cout = reg_acc[7];
end
4'b1000: c_bus = b_bus;
4'b1001: c_bus = reg_acc;
default: begin
c_bus = 8'hxx;
cout = 1'bx;
end
endcase
end
// Define ALU flag register
assign flag_Z = ~(|c_bus);
assign flag_C = cout;
assign flag_P = ~c_bus[7];
assign flagsIN = {flag_C,flag_P,flag_Z};
// FLAG SELECTION MUX
always @(flag_mux or c_bus or flagsIN)
case (flag_mux)
1'b1: flag_mux_out = flagsIN; // Load from ALU output
1'b0: flag_mux_out = c_bus[2:0]; // Load from reg_oplo
endcase
// REGISTER THE FLAG
always @(posedge sys_clk or negedge sys_rst_l)
if (~sys_rst_l) reg_flag <= 3'b000;
else if (load_flagH) reg_flag <= flag_mux_out;
//
// Define B MUX
//
always @(reg_ax or reg_bx or reg_flag or reg_pc or
d_bus or bbus_mux
`ifdef use_reg_port
or reg_port
`endif
)
case (bbus_mux)
3'b001: b_bus = reg_ax;
3'b010: b_bus = reg_bx;
3'b011: b_bus = reg_pc[7:0];
3'b100: b_bus = reg_flag;
`ifdef use_reg_port
3'b101: b_bus = reg_port;
`endif
3'b110: b_bus = d_bus[7:0];
3'b111: b_bus = reg_pc[(`AW-1):8];
default: b_bus= 8'hxx;
endcase
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -