科大OJ
其对应的英文版:HDLBits刷题网站
module top_module(output one);
assign one = 1;
endmodule
module top_module(
output zero
);// Module body starts after semicolon
assign zero = 0;
endmodule
module top_module(input in, output out);
assign out = in;
endmodule
module top_module(
input a, b, c,
output w, x, y, z
);
assign w=a;
assign x=b;
assign y=b;
assign z=c;
endmodule
module top_module(
input in,
output out
);
assign out=~in;
endmodule
module top_module(
input a, b,
output out
);
assign out=a & b;
endmodule
module top_module(
input a, b,
output out
);
assign out=!(a | b);
endmodule
module top_module(
input a, b,
output out
);
assign out = !(a ^ b);
endmodule
module top_module(
input a,
input b,
input c,
input d,
output out,
output out_n
);
// 请用户在下方编辑代码
wire a_and_b, c_and_d, or_out;
assign a_and_b = a&b;
assign c_and_d = c&d;
assign or_out = a_and_b | c_and_d;
assign out = or_out;
assign out_n = ~or_out;
//用户编辑到此为止
endmodule
module top_module (
input wire [2:0] vec,
output wire [2:0] outv,
output wire o2,
output wire o1,
output wire o0);
// Module body starts after module declaration
// 请用户在下方编辑代码
assign outv[2:0] = vec[2:0];
assign o0 = vec[0];
assign o1 = vec[1];
assign o2 = vec[2];
// 用户编辑到此为止
endmodule
`default_nettype none // Disable implicit nets. Reduces some types of bugs.
module top_module(
input wire [15:0] in,
output wire [7:0] out_hi,
output wire [7:0] out_lo
);
// Write your code here
assign out_hi = in[15:8];
assign out_lo = in[7:0];
endmodule
module top_module(
input [31:0] in,
output [31:0] out
);
assign out[31:24] = in[7:0];
assign out[23:16] = in[15:8];
assign out[15:8] = in[23:16];
assign out[7:0] = in[31:24];
endmodule
module top_module(
input [2:0] a,
input [2:0] b,
output [2:0] out_or_bitwise,
output out_or_logical,
output [5:0] out_not
);
// Write your code here
assign out_not[5:0] = ~({b[2:0],a[2:0]});
assign out_or_bitwise = a | b;
assign out_or_logical = a[0]|a[1]|a[2]|b[0]|b[1]|b[2];
endmodule
module top_module(
input [3:0] in,
output out_and,
output out_or,
output out_xor
);
/*
assign out_and = in[0]&in[1]&in[2]&in[3];
assign out_or = in[0]|in[1]|in[2]|in[3];
assign out_xor = in[0]^in[1]^in[2]^in[3];
*/
assign out_and = &in[2:0];
assign out_or = |in[2:0];
assign out_xor = ^in[2:0];
endmodule
module top_module (
input [4:0] a, b, c, d, e, f,
output [7:0] w, x, y, z );
// assign { ... } = { ... };
assign {w, x, y, z} = {a, b, c, d, e, f, 2'b11};
endmodule
module top_module(
input [7:0] in,
output [7:0] out
);
assign out = {in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7]};
endmodule
module top_module (
input [7:0] in,
output [31:0] out );//
assign out = {{24{in[7]}},in[7:0]};
endmodule
module top_module (
input a, b, c, d, e,
output [24:0] out );//
// The output is XNOR of two vectors created by
// concatenating and replicating the five inputs.
assign out = ~({ {5{a}}, {5{b}},{5{c}},{5{d}}, {5{e}}} ^ { 5{a, b, c, d, e} });
endmodule
module top_module(
input a,
input b,
output out
);
// 请用户在下方编辑代码
mod_a imod_a1(
.in1(a),
.in2(b),
.out(out)
);
//用户编辑到此为止
endmodule
module mod_a (
input in1,
input in2,
output out
);
assign out = in1 & in2;
endmodule
module mod_a(
output out1, out2,
input in1,in2,in3,in4);
assign out1 = in1 & in2 & in3 & in4; //这只是一个简单的示例
assign out2 = in1 | in2 | in3 | in4; //这只是一个简单的示例
endmodule
module top_module(
input a,
input b,
input c,
input d,
output out1,
output out2
);
// 请用户在下方编辑代码
mod_a imod_a1(out1, out2, a, b, c, d);
// 用户编辑到此为止
endmodule
module mod_a (
output out1 ,
output out2 ,
input in1 ,
input in2 ,
input in3 ,
input in4
);
assign out1 = in1 & in2 & in3 & in4; //这只是一个简单的示例
assign out2 = in1 | in2 | in3 | in4; //这只是一个简单的示例
endmodule
module top_module (
input a ,
input b ,
input c ,
input d ,
output out1,
output out2
);
//Write your code here
mod_a imod_a1(
.out1(out1),
.out2(out2),
.in1(a),
.in2(b),
.in3(c),
.in4(d)
);
endmodule
module my_dff(input clk,input d,output reg q);
always@(posedge clk)
q <= d;
endmodule
module top_module ( input clk, input d, output q );
// Write your code here
wire t1, t2;
my_dff idff1(clk, d, t1);
my_dff idff2(clk, t1, t2);
my_dff idff3(clk, t2, q);
endmodule
module my_dff8(
input clk,
input [7:0] d,
output reg [7:0] q
);
always@(posedge clk)
q <= d;
endmodule
module top_module(
input clk,
input [7:0] d,
input [1:0] sel,
output reg [7:0] q
);
// Write your code here
wire [7:0]t1;
wire [7:0]t2;
wire [7:0]t3;
my_dff8 idff8_1(clk, d, t1);
my_dff8 idff8_2(clk, t1, t2);
my_dff8 idff8_3(clk, t2, t3);
always @(*) begin
case(sel)
2'd0: q <= d;
2'd1: q <= t1;
2'd2: q <= t2;
2'd3: q <= t3;
endcase
end
endmodule
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
assign {cout,sum} = a + b + cin;
endmodule
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire c;
add16 iadd16_1(.a(a[15:0]), .b(b[15:0]), .cin(0), .sum(sum[15:0]), .cout(c));
add16 iadd16_2(.a(a[31:16]), .b(b[31:16]), .cin(c), .sum(sum[31:16]), .cout());
endmodule
module add1 ( input a, input b, input cin, output sum, output cout );
// Full adder module here
assign sum = a ^ b ^ cin;
assign cout = (a&b)|(a&cin)|(b&cin);
endmodule
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);//
wire c;
add16 a0(.a(a[15:0]), .b(b[15:0]), .cin(1'b0), .sum(sum[15:0]), .cout(c));
add16 a1(.a(a[31:16]), .b(b[31:16]), .cin(c), .sum(sum[31:16]), .cout());
endmodule
module add16 (
input[15:0] a,
input[15:0] b,
input cin,
output[15:0] sum,
output cout
);
assign {cout,sum} = a + b + cin;
endmodule
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0]sum_0;
wire [15:0]sum_1;
wire c;
add16 iadd16_high_0(.a(a[31:16]), .b(b[31:16]), .cin(0), .sum(sum_0), .cout());
add16 iadd16_high_1(.a(a[31:16]), .b(b[31:16]), .cin(1), .sum(sum_1), .cout());
add16 iadd16_low(.a(a[15:0]), .b(b[15:0]), .cin(0), .sum(sum[15:0]), .cout(c));
assign sum[31:16] = (c == 1 ? sum_1 : sum_0);
endmodule
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
assign {cout,sum} = a + b + cin;
endmodule
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire [31:0]b2 = b ^ {32{sub}};
wire c;
add16 iadd16_1(.a(a[15:0]), .b(b2[15:0]), .cin(sub), .sum(sum[15:0]), .cout(c));
add16 iadd16_2(.a(a[31:16]), .b(b2[31:16]), .cin(c), .sum(sum[31:16]), .cout());
endmodule
module top_module(
input a,
input b,
output wire out_assign,
output reg out_alwaysblock
);
assign out_assign = a & b;
always @(*) begin
out_alwaysblock <= a & b;
end
endmodule
module top_module(
input clk,
input a,
input b,
output wire out_assign,
output reg out_always_comb,
output reg out_always_ff
);
// 请用户在下方编辑代码
assign out_assign = a ^ b;
//reg不一定非要在电路中引入寄存器
always @(*) begin
out_always_comb = a ^ b;
end
always @(posedge clk) begin
out_always_ff <= a ^ b;
end
//用户编辑到此为止
endmodule
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always);
// 请用户在下方编辑代码
wire [1:0]sel = {sel_b1, sel_b2};
assign out_assign = (sel == 3 ? b : a);
always @(*) begin
if(sel == 3) out_always = b;
else out_always = a;
end
//用户编辑到此为止
endmodule
module top_module (
input cpu_overheated ,
output reg shut_off_computer ,
input arrived ,
input gas_tank_empty ,
output reg keep_driving
);
// Edit the code below
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1'b1;
else
shut_off_computer = 1'b0;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
else
keep_driving = 0;
end
endmodule
module top_module (
input [2:0] sel,
input [3:0] data0,
input [3:0] data1,
input [3:0] data2,
input [3:0] data3,
input [3:0] data4,
input [3:0] data5,
output reg [3:0] out );//
always@(*) begin // This is a combinational circuit
case(sel)
0: out = data0;
1: out = data1;
2: out = data2;
3: out = data3;
4: out = data4;
5: out = data5;
default: out = 3'b0;
endcase
end
endmodule
module top_module(
input [3:0] in,
output reg [1:0] pos
);
// Write your code here
always @(*) begin
case(in)
4'b0000: pos = 0;
4'b0001: pos = 0;
4'b0010: pos = 1;
4'b0011: pos = 0;
4'b0100: pos = 2;
4'b0101: pos = 0;
4'b0110: pos = 1;
4'b0111: pos = 0;
4'b1000: pos = 3;
4'b1001: pos = 0;
4'b1010: pos = 1;
4'b1011: pos = 0;
4'b1100: pos = 2;
4'b1101: pos = 0;
4'b1110: pos = 1;
4'b1111: pos = 0;
endcase
end
endmodule
module top_module (
input [7:0] in,
output reg [2:0] pos );
always @(*) begin
casez(in)
8'bzzzz_zzz1: pos = 0;
8'bzzzz_zz1z: pos = 1;
8'bzzzz_z1zz: pos = 2;
8'bzzzz_1zzz: pos = 3;
8'bzzz1_zzzz: pos = 4;
8'bzz1z_zzzz: pos = 5;
8'bz1zz_zzzz: pos = 6;
8'b1zzz_zzzz: pos = 7;
default: pos = 0;
endcase
end
endmodule
module top_module (
input [15:0] scancode,
output reg left,
output reg down,
output reg right,
output reg up );
always @(*) begin
up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
case(scancode)
16'he06b: left = 1;
16'he072: down = 1;
16'he074: right = 1;
16'he075: up = 1;
endcase
end
endmodule
module top_module (
input [7:0] a, b, c, d,
output [7:0] min);
wire [7:0] min_ab = a < b ? a : b;
wire [7:0] min_cd = c < d ? c : d;
assign min = min_ab < min_cd ? min_ab : min_cd;
endmodule
module top_module (
input [7:0] in,
output parity);
assign parity = ^in[7:0];
endmodule
module top_module (
input clk, // Clocks are used in sequential circuits
input d,
output reg q );//
// Use a clocked always block
// copy d to q at every positive edge of clk
// Clocked always blocks should use non-blocking assignments
always @(posedge clk) begin
q <= d;
end
endmodule
module top_module (
input clk,
input [7:0] d,
output reg [7:0] q
);
// 请用户在下方编辑代码
always @(posedge clk) begin
q <= d;
end
//用户编辑到此为止
endmodule
module top_module (
input clk,
input reset, // Synchronous reset
input [7:0] d,
output reg [7:0] q
);
always @(posedge clk) begin
if (reset) q <= 8'b0;
else q <= d;
end
endmodule
module top_module (
input clk ,
input reset ,
input [7:0] d ,
output reg [7:0] q
);
// Write your code here
always @(negedge clk) begin
if(reset) q <= 8'h34;
else q <= d;
end
endmodule
module top_module (
input clk,
input areset, // active high asynchronous reset
input [7:0] d,
output reg [7:0] q
);
// Write your code here
always @(posedge clk or posedge areset) begin
if (areset) q <= 8'b0;
else q <= d;
end
endmodule
module top_module(
input clk,
input resetn,
input [1:0] byteena,
input [15:0] d,
output reg [15:0] q
);
// Write your code here
always @(posedge clk) begin
if(~resetn) q <= 16'b0;
else begin
q[15:8] <= byteena[1] == 1 ? d[15:8] : q[15:8];
q[7:0] <= byteena[0] == 1 ? d[7:0] : q[7:0];
end
end
endmodule
module top_module (
input clk,
input in,
output reg out);
wire d = out ^ in;
always @(posedge clk) begin
out <= d;
end
endmodule
module top_module (
input clk,
input x,
output z
);
reg q1, q2, q3;
wire d1 = x ^ q1;
wire d2 = x & ~q2;
wire d3 = x | ~q3;
assign z = ~(q1|q2|q3);
initial begin
q1 = 0;
q2 = 0;
q3 = 0;
end
always @(posedge clk) begin
q1 <= d1;
q2 <= d2;
q3 <= d3;
end
endmodule
module top_module (
input clk,
input in,
output reg out = 0
);
wire prev_in;
dff idff_1(.clk(clk), .d(in), .q(prev_in));
always @(posedge clk) begin
if(~prev_in & in) out <= 1;
else out <= 0;
end
endmodule
module dff(
input clk,
input d,
output reg q
);
initial q = 0;
always @(posedge clk) begin
q <= d;
end
endmodule
module top_module (
input clk,
input in,
output reg out
);
//initial out = 0;
wire prev_in;
dff idff_1(.clk(clk), .d(in), .q(prev_in));
always @(posedge clk) begin
out <= prev_in ^ in;
end
endmodule
module dff (
input clk,
input d,
output reg q
);
always @(posedge clk) begin
q <= d;
end
endmodule
module top_module (
input clk,
input reset, // 异步复位,高电平有效,复位值为0
output reg [3:0] q);
always @(posedge clk or posedge reset) begin
if(reset) q <= 0;
else if(q == 15) q <= 0;
else q <= q + 1;
end
endmodule
module top_module (
input clk , //时钟信号
input reset , //同步高电平有效复位信号
output reg [3:0] q //计数结果
);
// 请用户在下方编辑代码
always @(posedge clk) begin
if(reset) q <= 1;
else if(q == 10) q <= 1;
else q <= q + 1;
end
//用户编辑到此为止
endmodule
module top_module(
input clk,
input reset,
input en,
output reg [3:0]q);
always @(posedge clk) begin
if(reset) q <= 5;
else if (~en) q <= q;
else if (q == 5) q <= 15;
else q <= q - 1;
end
endmodule
module top_module(
input clk , //4Hz
input reset ,
output [7:0] ss
);
// Write your code here
reg [1:0]cnt;
reg [3:0]ones_place;
reg [3:0]tens_place;
//initial begin cnt = 0; ones_place = 0; tens_place = 0;end
assign ss[3:0] = ones_place[3:0];
assign ss[7:4] = tens_place[3:0];
always @(posedge clk) begin
if(reset) begin cnt <= 0; ones_place <= 0; tens_place <= 0; end
else if(cnt == 3) begin
cnt <= 0;
if(ones_place == 9) begin
ones_place <= 0;
if (tens_place == 5) tens_place <= 0;
else tens_place <= tens_place + 1;
end else begin
ones_place <= ones_place + 1;
end
end else begin
cnt <= cnt + 1;
end
end
endmodule
module top_module(
input clk,
input areset, //异步、高有效、复位值为0
input load,
input ena,
input [3:0] data,
output reg [3:0] q);
//Write your code here
always @(posedge clk or posedge areset) begin
if(areset) q <= 0;
else if(load) q <= data;
else if(ena) q <= q >> 1;
else q <= q;
end
endmodule
module top_module(
input clk,
input enable,
input S,
input A, B, C,
output reg Z
);
// Write your code here
reg [7:0]q;
//initial begin q <= 0; end
always @(posedge clk) begin
if(enable) begin q <= {q[6:0], S}; end
else begin q <= q; end
end
always @(*) begin
Z = q[{A, B, C}];
end
endmodule
module top_module(
input [2:0] addr,
output [3:0] q
);
reg [3:0]mem[7:0];
integer i = 0;
initial begin
for (i = 0; i < 8; i = i + 1) begin
mem[i] = i;
end
end
assign q = mem[addr];
endmodule
module ram_one_port(
input clk,
input wr_en,
input [2:0] wr_addr,
input [15:0] wr_data,
input [2:0] rd_addr,
output [15:0] rd_data);
reg [15:0]mem[7:0];
initial begin $readmemh("memfile.dat", mem); end
assign rd_data = mem[rd_addr];
always @(posedge clk) begin
if(wr_en) mem[wr_addr] <= wr_data;
end
endmodule
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output reg out);//
always @(posedge clk or posedge areset) begin
if(areset) out <= 1;
else if(in == 0) out <= ~out;
else out <= out;
end
endmodule
module top_module (
input sel,
input [7:0] a,
input [7:0] b,
output [7:0]out );
assign out = ({8{~sel}} & a) | ({8{sel}} & b);
endmodule
//`timescale 1ns/1ns
module tb();
reg a,b;
initial begin
a = 1'b1;
b = 1'b0;
#10
a = 1'b1;
b = 1'b1;
#10
a = 1'b0;
b = 1'b1;
#10
a = 1'b0;
b = 1'b0;
#10
a = 1'b1;
b = 1'b0;
#10
$finish;
end
endmodule
module tb();
reg a,b;
wire q;
//对ab信号进行初始化
initial begin
a = 0; b = 0;
#3
b = 1;
#2
a = 1; b = 0;
#2
b = 1;
#2
a = 0; b = 0;
#2
a = 0; b = 1;
#2
a = 1; b = 0;
#2
b = 1;
#2
a = 0; b = 0;
//$finish;
end
//例化mymodule模块
mymodule imymodule_1(.a(a), .b(b), .q(q));
endmodule
module mymodule(
input a,b,
output q
);
assign q = a & b;
endmodule
module tb();
wire [2:0]out;//必要输出信号
//信号定义
reg clk;
initial clk = 0;
//信号生成
always #5 clk = ~clk;
//模块例化
dut idut_1(.clk(clk), .out(out));
endmodule
module dut(input clk, output reg [2:0]out);
//测试模块
always @(posedge clk)
out <= out + 1'b1;
endmodule
module ram_one_port(
input clk,
input [1:0] addr,
input wr_en,
input [7:0] wr_data,
output [7:0] rd_data
);
reg [7:0] mem[3:0];
initial
begin
mem[0] = 8'b0;
mem[1] = 8'b0;
mem[2] = 8'b0;
mem[3] = 8'b0;
end
assign rd_data = mem[addr];
always@(posedge clk)
begin
if(wr_en)
mem[addr] <= wr_data;
end
endmodule
module tb(
);
//信号定义
reg clk,wr_en;
reg [1:0] addr;
reg [7:0] wr_data;
wire [7:0] rd_data;
//信号生成
initial begin
clk = 0;
forever #5 clk = ~clk; //生成周期为10的一个时钟信号
end
initial begin
addr = 2'b0;
@(posedge clk);
repeat(4) begin //repeat为verilog关键字,表示重复操作
@(posedge clk); //等待clk信号的上升沿到来
#1 addr = addr + 1; //clk上升沿1个时间单位后,addr加一
end
end
initial begin
wr_en = 0;
#16; //延时一段时间,
@(posedge clk);
#1 wr_en = 1;
@(posedge clk);
@(posedge clk);
#1 wr_en = 0;
end
initial begin
wr_data = 8'h0;
repeat(4) begin
wait(wr_en==1'b1);
#1 wr_data = $random%256;
@(posedge clk);
end
end
//例化被测模块
ram_one_port ram_inst(
.clk(clk),
.wr_en(wr_en),
.addr(addr),
.wr_data(wr_data),
.rd_data(rd_data)
);
endmodule
module top_module(
input clk,
input [4:0] A1,A2,A3,
input [31:0] WD,
input WE,
output [31:0] RD1,RD2
);
reg [31:0] reg_file[0:31];
//初始化寄存器堆
integer i;
initial
begin
for(i=0;i<32;i=i+1) reg_file[i] = 0;
end
//写入寄存器
always@(posedge clk)
begin
if(WE) begin
if(A3 != 0) reg_file[A3] <= WD;
end
/*待填*/
end
//读取寄存器
assign RD1 = reg_file[A1];/*待填*/
assign RD2 = reg_file[A2];/*待填*/
endmodule
module top_module(
input clk,
input rst,
input JUMP,
input [31:0] JUMP_PC,
output reg [31:0] pc);
wire [31:0] pc_plus4;
assign pc_plus4 = pc + 32'h4;
//计算PC
always@(posedge clk or posedge rst)
begin
/*待填*/
if(rst == 1) pc <= 32'b0;
else if(JUMP) pc <= JUMP_PC;
else pc <= pc_plus4;
end
endmodule
module top_module(
input [31:0] inst,
output reg [31:0] out
);
wire [6:0] opcode;
assign opcode= inst[6:0];
//立即数扩展
initial out = 32'b0;
always@(*)
begin
case(opcode)
7'b0010111: begin out[31:12] = inst[31:12]; end //auipc
7'b0110111: begin out[31:12] = inst[31:12]; end //lui
7'b1100011: begin //B type
out[12] = inst[31];
out[11] = inst[7];
out[10:5] = inst[30:25];
out[4:1] = inst[11:8];
out[31:13] = {19{out[12]}};
end
7'b1101111: begin //jal
out[20] = inst[31];
out[19:12] = inst[19:12];
out[11] = inst[20];
out[10:1] = inst[30:21];
out[31:21] = {10{out[20]}};
end
7'b1100111: begin //jalr->I type
out[11:0] = inst[31:20];
out[31:12] = {20{out[11]}};
end
7'b0000011: begin //I type
out[11:0] = inst[31:20];
out[31:12] = {20{out[11]}};
end
7'b0100011: begin //S type
out[11:5] = inst[31:25];
out[4:0] = inst[11:7];
end
7'b0010011: begin //I type
out[11:0] = inst[31:20];
out[31:12] = {20{out[11]}};
end
default: out = 32'b0;
endcase
end
endmodule
module top_module(
input [31:0] REG1,
input [31:0] REG2,
input [2:0] Type,
output reg BrE
);
wire signed [31:0] signed_REG1;
wire signed [31:0] signed_REG2;
//wire unsigned [31:0] unsigned_REG1;
//wire unsigned [31:0] unsigned_REG2;
assign signed_REG1 = REG1;
assign signed_REG2 = REG2;
//assign unsigned_REG1 = REG1;
//assign unsigned_REG2 = REG2;
always@(*)
begin
case(Type)
3'b010: BrE = signed_REG1 == signed_REG2 ? 1 : 0; //beq
3'b011: BrE = signed_REG1 != signed_REG2 ? 1 : 0; //bne
3'b100: BrE = signed_REG1 < signed_REG2 ? 1 : 0; //blt
3'b101: BrE = signed_REG1 >= signed_REG2 ? 1 : 0; //bge
3'b110: begin //bltu
case({signed_REG1[31], signed_REG2[31]})
2'b00: BrE = signed_REG1 < signed_REG2;
2'b01: BrE = 1;
2'b10: BrE = 0;
2'b11: BrE = signed_REG1 < signed_REG2;
endcase
end
3'b111: begin //bgeu
case({signed_REG1[31], signed_REG2[31]})
2'b00: BrE = signed_REG1 >= signed_REG2;
2'b01: BrE = 0;
2'b10: BrE = 1;
2'b11: BrE = signed_REG1 >= signed_REG2;
endcase
end
default: BrE = 0;
/*待填*/
endcase
end
endmodule
module top_module(
input [31:0] SrcA,SrcB,
input [3:0] func,
output reg [31:0] ALUout
);
wire signed [31:0] signed_a;
wire signed [31:0] signed_b;
assign signed_a = SrcA;
assign signed_b = SrcB;
always@(*)
begin
case(func)
4'b0000: ALUout = signed_a + signed_b; //add
4'b1000: ALUout = signed_a - signed_b; //sub
4'b0001: ALUout = signed_a << signed_b[4:0]; //sll
4'b0010: ALUout = signed_a < signed_b ? 1 : 0; //lt
4'b0011: begin //ltu
case({signed_a[31], signed_b[31]})
2'b00: ALUout = signed_a < signed_b;
2'b01: ALUout = 1;
2'b10: ALUout = 0;
2'b11: ALUout = signed_a < signed_b;
endcase
end
4'b0100: ALUout = signed_a ^ signed_b; //xor
4'b0101: ALUout = signed_a >> signed_b[4:0]; //srl
4'b1101: ALUout = signed_a >>> signed_b[4:0]; //sra
4'b0110: ALUout = signed_a | signed_b; //or
4'b0111: ALUout = signed_a & signed_b; //and
4'b1110: ALUout = signed_b; //
default: ALUout = 0;
/*待填*/
endcase
end
endmodule
module top_module(
input clk,
input [31:0] im_addr,
output [31:0] im_dout,
input [2:0] dm_rd_ctrl,
input [1:0] dm_wr_ctrl,
input [31:0] dm_addr,
input [31:0] dm_din,
output reg [31:0] dm_dout
);
reg [3:0] byte_en;
reg [31:0] mem[0:4095]; //4K*32 = 16KB
reg [31:0] mem_out;
integer i;
initial
begin
for(i=0;i<4095;i=i+1) mem[i] = 0;
end
initial
begin
$readmemh("./problem/inst.dat",mem);
end
assign im_dout = {im_addr[31:14], im_addr[1:0]} == 0 ? mem[im_addr] : 0;
//由于不能跨单位读取数据,地址最低两位的数值决定了当前单位能读取到的数据,即mem_out
always@(*)
begin
case(dm_addr[1:0])
2'b00: mem_out = mem[dm_addr[13:2]][31:0];
2'b01: mem_out = {8'h0,mem[dm_addr[13:2]][31:8]};
2'b10: mem_out = {16'h0,mem[dm_addr[13:2]][31:16]};
2'b11: mem_out = {24'h0,mem[dm_addr[13:2]][31:24]};
endcase
end
always@(*)
begin
case(dm_rd_ctrl)
3'b001: begin //lb
case(dm_addr[1:0])
2'b00: dm_dout = {{24{mem[{dm_addr[13:2], 2'b00}][7]}}, mem[{dm_addr[13:2], 2'b00}][7:0]};
2'b01: dm_dout = {{24{mem[{dm_addr[13:2], 2'b00}][15]}}, mem[{dm_addr[13:2], 2'b00}][15:7]};
2'b10: dm_dout = {{24{mem[{dm_addr[13:2], 2'b00}][23]}}, mem[{dm_addr[13:2], 2'b00}][23:16]};
2'b11: dm_dout = {{24{mem[{dm_addr[13:2], 2'b00}][31]}}, mem[{dm_addr[13:2], 2'b00}][31:24]};
endcase
end
3'b010: begin //lbu
case(dm_addr[1:0])
2'b00: dm_dout = {24'b0, mem[{dm_addr[13:2], 2'b00}][7:0]};
2'b01: dm_dout = {24'b0, mem[{dm_addr[13:2], 2'b00}][15:7]};
2'b10: dm_dout = {24'b0, mem[{dm_addr[13:2], 2'b00}][23:16]};
2'b11: dm_dout = {24'b0, mem[{dm_addr[13:2], 2'b00}][31:24]};
endcase
end
3'b011: begin //lh
case(dm_addr[1:0])
2'b00: dm_dout = {{16{mem[{dm_addr[13:2], 2'b00}][15]}}, mem[{dm_addr[13:2], 2'b00}][15:0]};
2'b10: dm_dout = {{16{mem[{dm_addr[13:2], 2'b00}][31]}}, mem[{dm_addr[13:2], 2'b00}][31:16]};
default: dm_dout = 0;
endcase
end
3'b100: begin //lhu
case(dm_addr[1:0])
2'b00: dm_dout = {16'b0, mem[{dm_addr[13:2], 2'b00}][15:0]};
2'b10: dm_dout = {16'b0, mem[{dm_addr[13:2], 2'b00}][31:16]};
default: dm_dout = 0;
endcase
end
3'b101: dm_dout = mem_out; //lw
default: dm_dout = 0;
endcase
end
always@(*)
begin
if(dm_wr_ctrl == 2'b11)
byte_en = 4'b1111;
else if(dm_wr_ctrl == 2'b10)
begin
if(dm_addr[1] == 1'b1)
byte_en = 4'b1100;
else
byte_en = 4'b0011;
end
else if(dm_wr_ctrl == 2'b01)
begin
case(dm_addr[1:0])
2'b00: byte_en = 4'b0001;
2'b01: byte_en = 4'b0010;
2'b10: byte_en = 4'b0100;
2'b11: byte_en = 4'b1000;
endcase
end
else
byte_en = 4'b0000;
end
always@(posedge clk)
begin
if((byte_en != 1'b0)&&(dm_addr[30:12]==19'b0))
begin
case(byte_en)
4'b0001: mem[{dm_addr[11:2], 2'b00}][7:0] <= dm_din[7:0];
4'b0010: mem[{dm_addr[11:2], 2'b00}][15:8] <= dm_din[7:0];
4'b0100: mem[{dm_addr[11:2], 2'b00}][23:16] <= dm_din[7:0];
4'b1000: mem[{dm_addr[11:2], 2'b00}][31:24] <= dm_din[7:0];
4'b0011: mem[{dm_addr[11:2], 2'b00}][15:0] <= dm_din[15:0];
4'b1100:mem[{dm_addr[11:2], 2'b00}][31:16] <= dm_din[15:0];
4'b1111:mem[{dm_addr[11:2], 2'b00}] <= dm_din;
endcase
end
end
endmodule
//module controler(
module top_module(
input [31:0] inst,
output rf_wr_en,
output reg [1:0] rf_wr_sel,
output do_jump,
output reg [2:0] BrType,
output alu_a_sel,
output alu_b_sel,
output reg [3:0] alu_ctrl,
output reg [2:0] dm_rd_ctrl,
output reg [1:0] dm_wr_ctrl
);
wire [6:0] opcode;
wire [2:0] funct3;
wire [6:0] funct7;
wire is_lui;
wire is_auipc;
wire is_jal;
wire is_jalr;
wire is_beq;
wire is_bne;
wire is_blt;
wire is_bge;
wire is_bltu;
wire is_bgeu;
wire is_lb;
wire is_lh;
wire is_lw;
wire is_lbu;
wire is_lhu;
wire is_sb;
wire is_sh;
wire is_sw;
wire is_addi;
wire is_slti;
wire is_sltiu;
wire is_xori;
wire is_ori;
wire is_andi;
wire is_slli;
wire is_srli;
wire is_srai;
wire is_add;
wire is_sub;
wire is_sll;
wire is_slt;
wire is_sltu;
wire is_xor;
wire is_srl;
wire is_sra;
wire is_or;
wire is_and;
wire is_add_type;
wire is_u_type;
wire is_jump_type;
wire is_b_type;
wire is_r_type;
wire is_i_type;
wire is_s_type;
assign opcode = inst[6:0];
assign funct7 = inst[31:25];
assign funct3 = inst[14:12];
assign is_lui = (opcode == 7'h37) ;
assign is_auipc= (opcode == 7'h17) ;
assign is_jal = (opcode == 7'h6F) ;
assign is_jalr = (opcode == 7'h67) && (funct3 ==3'h0) ;
assign is_beq = (opcode == 7'h63) && (funct3 ==3'h0) ;
assign is_bne = (opcode == 7'h63) && (funct3 ==3'h1) ;
assign is_blt = (opcode == 7'h63) && (funct3 ==3'h4) ;
assign is_bge = (opcode == 7'h63) && (funct3 ==3'h5) ;
assign is_bltu = (opcode == 7'h63) && (funct3 ==3'h6) ;
assign is_bgeu = (opcode == 7'h63) && (funct3 ==3'h7) ;
assign is_lb = (opcode == 7'h03) && (funct3 ==3'h0) ;
assign is_lh = (opcode == 7'h03) && (funct3 ==3'h1) ;
assign is_lw = (opcode == 7'h03) && (funct3 ==3'h2) ;
assign is_lbu = (opcode == 7'h03) && (funct3 ==3'h4) ;
assign is_lhu = (opcode == 7'h03) && (funct3 ==3'h5) ;
assign is_sb = (opcode == 7'h23) && (funct3 ==3'h0) ;
assign is_sh = (opcode == 7'h23) && (funct3 ==3'h1) ;
assign is_sw = (opcode == 7'h23) && (funct3 ==3'h2) ;
assign is_addi = (opcode == 7'h13) && (funct3 ==3'h0) ;
assign is_slti = (opcode == 7'h13) && (funct3 ==3'h2) ;
assign is_sltiu= (opcode == 7'h13) && (funct3 ==3'h3) ;
assign is_xori = (opcode == 7'h13) && (funct3 ==3'h4) ;
assign is_ori = (opcode == 7'h13) && (funct3 ==3'h6) ;
assign is_andi = (opcode == 7'h13) && (funct3 ==3'h7) ;
assign is_slli = (opcode == 7'h13) && (funct3 ==3'h1) && (funct7 == 7'h00);
assign is_srli = (opcode == 7'h13) && (funct3 ==3'h5) && (funct7 == 7'h00);
assign is_srai = (opcode == 7'h13) && (funct3 ==3'h5) && (funct7 == 7'h20);
assign is_add = (opcode == 7'h33) && (funct3 ==3'h0) && (funct7 == 7'h00);
assign is_sub = (opcode == 7'h33) && (funct3 ==3'h0) && (funct7 == 7'h20);
assign is_sll = (opcode == 7'h33) && (funct3 ==3'h1) && (funct7 == 7'h00);
assign is_slt = (opcode == 7'h33) && (funct3 ==3'h2) && (funct7 == 7'h00);
assign is_sltu = (opcode == 7'h33) && (funct3 ==3'h3) && (funct7 == 7'h00);
assign is_xor = (opcode == 7'h33) && (funct3 ==3'h4) && (funct7 == 7'h00);
assign is_srl = (opcode == 7'h33) && (funct3 ==3'h5) && (funct7 == 7'h00);
assign is_sra = (opcode == 7'h33) && (funct3 ==3'h5) && (funct7 == 7'h20);
assign is_or = (opcode == 7'h33) && (funct3 ==3'h6) && (funct7 == 7'h00);
assign is_and = (opcode == 7'h33) && (funct3 ==3'h7) && (funct7 == 7'h00);
assign is_add_type = is_auipc | is_jal | is_jalr | is_b_type | is_s_type
| is_lb | is_lh | is_lw | is_lbu | is_lhu | is_add | is_addi ;
assign is_u_type = is_lui | is_auipc ;
assign is_jump_type= is_jal ;
assign is_b_type = is_beq | is_bne | is_blt | is_bge | is_bltu | is_bgeu ;
assign is_r_type = is_add | is_sub | is_sll | is_slt | is_sltu | is_xor
| is_srl | is_sra | is_or | is_and ;
assign is_i_type = is_jalr | is_lb | is_lh | is_lw | is_lbu | is_lhu
| is_addi | is_slti | is_sltiu | is_xori | is_ori | is_andi
| is_slli | is_srli | is_srai ;
assign is_s_type = is_sb | is_sh | is_sw ;
//rf_wr_en
assign rf_wr_en = is_u_type | is_jump_type | is_i_type | is_r_type /*待填*/ ;
//[1:0]rf_wr_sel
always@(*)
begin
if(is_jal|is_jalr) rf_wr_sel = 2'b01;
else if(is_addi|is_slli|is_xori|is_srli|is_srai|is_ori|is_andi|is_r_type|is_u_type) rf_wr_sel = 2'b10;
else if(is_lb|is_lbu|is_lh|is_lhu|is_lw) rf_wr_sel = 2'b11;
else rf_wr_sel = 2'b00;
/*待填*/
end
//do_jump
assign do_jump = is_jal|is_jalr/*待填*/ ;
//[2:0]BrType
always@(*)
begin
if(is_beq) BrType = 3'b010;
else if(is_bne) BrType = 3'b011;
else if(is_blt) BrType = 3'b100;
else if(is_bge) BrType = 3'b101;
else if(is_bltu) BrType = 3'b110;
else if(is_bgeu) BrType = 3'b111;
else BrType = 3'b000;
/*待填*/
end
//alu_a_sel
assign alu_a_sel = is_r_type|is_i_type|is_s_type/*待填*/;
//alu_b_sel
assign alu_b_sel = ~is_r_type/*待填*/ ;
//alu_ctrl
always@(*)
begin
if(is_auipc|is_jal|is_jalr|is_b_type|is_s_type|is_lb|is_lbu|is_lh|is_lhu|is_lw|is_add|is_addi) alu_ctrl = 4'b0000;
else if(is_sub) alu_ctrl = 4'b1000;
else if(is_sll|is_slli) alu_ctrl = 4'b0001;
else if(is_srl|is_srli) alu_ctrl = 4'b0101;
else if(is_sra|is_srai) alu_ctrl = 4'b1101;
else if(is_slt|is_slti) alu_ctrl = 4'b0010;
else if(is_sltu|is_sltiu) alu_ctrl = 4'b0011;
else if(is_xor|is_xori) alu_ctrl = 4'b0100;
else if(is_or|is_ori) alu_ctrl = 4'b0110;
else if(is_and|is_andi) alu_ctrl = 4'b0111;
else if(is_lui) alu_ctrl = 4'b1110;
else alu_ctrl = 4'b0000;
/*待填*/
end
//[2:0]dm_rd_ctrl
always@(*)
begin
if(is_lb) dm_rd_ctrl = 3'b001;
else if(is_lbu) dm_rd_ctrl = 3'b010;
else if(is_lh) dm_rd_ctrl = 3'b011;
else if(is_lhu) dm_rd_ctrl= 3'b100;
else if(is_lw) dm_rd_ctrl = 3'b101;
else dm_rd_ctrl = 3'b000;
/*待填*/
end
//[1:0]dm_wr_ctrl
always@(*)
begin
if(is_sb) dm_wr_ctrl = 2'b01;
else if(is_sh) dm_wr_ctrl = 2'b10;
else if(is_sw) dm_wr_ctrl = 2'b11;
else dm_wr_ctrl = 2'b00;
/*待填*/
end
endmodule
module top_module(
input clk,
input rst
);
wire clk;
wire rst;
wire [31:0] inst;
wire [1:0] rf_wr_sel;
reg [31:0] rf_wd;
wire rf_wr_en;
wire [31:0] rf_rd1,rf_rd2;
wire [31:0] pc;
wire [31:0] pc_plus4;
wire do_jump;
wire JUMP;
wire [31:0] imm_out;
wire [2:0] comp_ctrl;
wire BrE;
wire alu_a_sel;
wire alu_b_sel;
wire [31:0] alu_a,alu_b,alu_out;
wire [3:0] alu_ctrl;
wire [2:0] dm_rd_ctrl;
wire [1:0] dm_wr_ctrl;
wire [31:0] dm_dout;
always@(*)
begin
case(rf_wr_sel)
2'b00: rf_wd = 32'h0;
2'b01: rf_wd = pc_plus4;
2'b10: rf_wd = alu_out;
2'b11: rf_wd = dm_dout;
default:rf_wd = 32'h0;
endcase
end
assign pc_plus4 = pc + 32'h4;
assign JUMP = BrE || do_jump;
assign alu_a = alu_a_sel ? rf_rd1 : pc ;
assign alu_b = alu_b_sel ? imm_out : rf_rd2 ;
reg_file reg_file0(
.clk (clk),
.A1 (inst[19:15]),
.A2 (inst[24:20]),
.A3 (inst[11:7]),
.WD (rf_wd),
.WE (rf_wr_en),
.RD1 (rf_rd1),
.RD2 (rf_rd2)
);
pc pc0(
.clk (clk),
.rst (rst),
.JUMP (JUMP),
.JUMP_PC (pc+imm_out), //?
.pc (pc)
);
imm imm0(
.inst (inst),
.out (imm_out)
);
branch branch0(
.REG1 (rf_rd1),
.REG2 (rf_rd2),
.Type (comp_ctrl),
.BrE (BrE)
);
alu alu0(
.SrcA (alu_a),
.SrcB (alu_b),
.func (alu_ctrl),
.ALUout (alu_out)
);
mem mem0(
.clk (clk),
.im_addr (pc),
.im_dout (inst),
.dm_rd_ctrl (dm_rd_ctrl),
.dm_wr_ctrl (dm_wr_ctrl),
.dm_addr (alu_out),
.dm_din (rf_rd2),
.dm_dout (dm_dout)
);
ctrl ctrl0(
.inst (inst),
.rf_wr_en (rf_wr_en),
.rf_wr_sel (rf_wr_sel),
.do_jump (do_jump),
.BrType (comp_ctrl),
.alu_a_sel (alu_a_sel),
.alu_b_sel (alu_b_sel),
.alu_ctrl (alu_ctrl),
.dm_rd_ctrl (dm_rd_ctrl),
.dm_wr_ctrl (dm_wr_ctrl)
);
endmodule