⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datapath.v

📁 键盘和USB与PC机的接口程序
💻 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 + -