Skip to content

Instantly share code, notes, and snippets.

@larryxiao
Last active August 29, 2015 14:02
Show Gist options
  • Save larryxiao/237e8b787bbc480a43a8 to your computer and use it in GitHub Desktop.
Save larryxiao/237e8b787bbc480a43a8 to your computer and use it in GitHub Desktop.
pastebin
module sc_cu (op, func, z, wmem, wreg, regrt, m2reg, aluc, shift,
aluimm, pcsource, jal, sext);
input [5:0] op,func;
input z;
output wreg,regrt,jal,m2reg,shift,aluimm,sext,wmem;
output [3:0] aluc;
output [1:0] pcsource;
wire r_type = ~|op;
wire i_add = r_type & func[5] & ~func[4] & ~func[3] &
~func[2] & ~func[1] & ~func[0]; //100000
wire i_sub = r_type & func[5] & ~func[4] & ~func[3] &
~func[2] & func[1] & ~func[0]; //100010
// please complete the deleted code.
// 100100
wire i_and = r_type & func[5] & ~func[4] & ~func[3] & func[2] & ~func[1] & ~func[0];
// 100101
wire i_or = r_type & func[5] & ~func[4] & ~func[3] & func[2] & ~func[1] & func[0];
// 100110
wire i_xor = r_type & func[5] & ~func[4] & ~func[3] & func[2] & func[1] & ~func[0];
// 000000
wire i_sll = r_type & ~func[5] & ~func[4] & ~func[3] & ~func[2] & ~func[1] & ~func[0];
// 000010
wire i_srl = r_type & ~func[5] & ~func[4] & ~func[3] & ~func[2] & func[1] & ~func[0];
// 000011
wire i_sra = r_type & ~func[5] & ~func[4] & ~func[3] & ~func[2] & func[1] & func[0];
// 001000
wire i_jr = r_type & ~func[5] & ~func[4] & func[3] & ~func[2] & ~func[1] & ~func[0];
//001000
wire i_addi = ~op[5] & ~op[4] & op[3] & ~op[2] & ~op[1] & ~op[0];
//001100
wire i_andi = ~op[5] & ~op[4] & op[3] & op[2] & ~op[1] & ~op[0];
// complete by yourself.
//001101
wire i_ori = ~op[5] & ~op[4] & op[3] & op[2] & ~op[1] & op[0];
//001110
wire i_xori = ~op[5] & ~op[4] & op[3] & op[2] & op[1] & ~op[0];
//100011
wire i_lw = op[5] & ~op[4] & ~op[3] & ~op[2] & op[1] & op[0];
//101011
wire i_sw = op[5] & ~op[4] & op[3] & ~op[2] & op[1] & op[0];
//000100
wire i_beq = ~op[5] & ~op[4] & ~op[3] & op[2] & ~op[1] & ~op[0];
//000101
wire i_bne = ~op[5] & ~op[4] & ~op[3] & op[2] & ~op[1] & op[0];
//001111
wire i_lui = ~op[5] & ~op[4] & op[3] & op[2] & op[1] & op[0];
//000010
wire i_j = ~op[5] & ~op[4] & ~op[3] & ~op[2] & op[1] & ~op[0];
//000011
wire i_jal = ~op[5] & ~op[4] & ~op[3] & ~op[2] & op[1] & op[0];
assign pcsource[1] = i_jr | i_j | i_jal;
assign pcsource[0] = ( i_beq & z ) | (i_bne & ~z) | i_j | i_jal ;
assign wreg = i_add | i_sub | i_and | i_or | i_xor |
i_sll | i_srl | i_sra | i_addi | i_andi |
i_ori | i_xori | i_lw | i_lui | i_jal;
// complete by yourself.
assign aluc[3] = i_sra;
assign aluc[2] = i_sub | i_or | i_srl | i_sra | i_beq | i_bne | i_lui;
assign aluc[1] = i_xor | i_sll | i_srl | i_sra | i_lui;
assign aluc[0] = i_and | i_or | i_sll | i_srl | i_sra;
assign shift = i_sll | i_srl | i_sra ;
// complete by yourself.
assign aluimm = i_addi | i_andi | i_ori | i_xori | i_lw | i_sw | i_beq | i_bne | i_lui;
assign sext = i_addi | i_andi | i_ori | i_xori | i_lw | i_sw | i_beq | i_bne | i_lui;
assign wmem = i_sw;
assign m2reg = i_lw;
assign regrt = i_addi | i_andi | i_ori | i_xori | i_lw | i_lui;
assign jal = i_jal;
endmodule
module sc_cu (clock, icode, ifun, zf, sf, of, wmem, wra, wrb, wesp, aluc, rasource, rbsource, pcsource, pushl, popl, ret, call, cc);
input [3:0] icode,ifun;
input clock, zf, sf, of;
output wmem, wra, wrb, wesp, rbsource, pushl, popl, ret, call, cc;
output [3:0] aluc;
output [1:0] rasource, pcsource;
// movl
wire rrmovl = ~icode[3] & ~icode[2] & icode[1] & ~icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ~ifun[0]; //0010 0000(2 0)
wire irmovl = ~icode[3] & ~icode[2] & icode[1] & icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ~ifun[0]; //0011 0000(3 0)
wire rmmovl = ~icode[3] & icode[2] & ~icode[1] & ~icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ~ifun[0]; //0100 0000(4 0)
wire mrmovl = ~icode[3] & icode[2] & ~icode[1] & icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ~ifun[0]; //0101 0000(5 0)
// opl
wire addl = ~icode[3] & icode[2] & icode[1] & ~icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ~ifun[0]; //0110 0000(6 0)
wire subl = ~icode[3] & icode[2] & icode[1] & ~icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ifun[0]; //0110 0001(6 1)
wire andl = ~icode[3] & icode[2] & icode[1] & ~icode[0] & ~ifun[3] & ~ifun[2] & ifun[1] & ~ifun[0]; //0110 0010(6 2)
wire xorl = ~icode[3] & icode[2] & icode[1] & ~icode[0] & ~ifun[3] & ~ifun[2] & ifun[1] & ifun[0]; //0110 0011(6 3)
// jxx
wire jmp = ~icode[3] & icode[2] & icode[1] & icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ~ifun[0]; //0111 0000(7 0)
wire jle = ~icode[3] & icode[2] & icode[1] & icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ifun[0]; //0111 0001(7 1)
wire jl = ~icode[3] & icode[2] & icode[1] & icode[0] & ~ifun[3] & ~ifun[2] & ifun[1] & ~ifun[0]; //0111 0010(7 2)
wire je = ~icode[3] & icode[2] & icode[1] & icode[0] & ~ifun[3] & ~ifun[2] & ifun[1] & ifun[0]; //0111 0011(7 3)
wire jne = ~icode[3] & icode[2] & icode[1] & icode[0] & ~ifun[3] & ifun[2] & ~ifun[1] & ~ifun[0]; //0111 0100(7 4)
wire jge = ~icode[3] & icode[2] & icode[1] & icode[0] & ~ifun[3] & ifun[2] & ~ifun[1] & ifun[0]; //0111 0101(7 5)
wire jg = ~icode[3] & icode[2] & icode[1] & icode[0] & ~ifun[3] & ifun[2] & ifun[1] & ~ifun[0]; //0111 0110(7 6)
//call
assign call = icode[3] & ~icode[2] & ~icode[1] & ~icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ~ifun[0]; //1000 0000(8 0)
//ret
assign ret = icode[3] & ~icode[2] & ~icode[1] & icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ~ifun[0]; //1001 0000(9 0)
//pushl
assign pushl = icode[3] & ~icode[2] & icode[1] & ~icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ~ifun[0]; //1010 0000(a 0)
//popl
assign popl = icode[3] & ~icode[2] & icode[1] & icode[0] & ~ifun[3] & ~ifun[2] & ~ifun[1] & ~ifun[0]; //1011 0000(b 0)
// 00 PC += length
// 01 jxx call
// 10 jmp reg
// mux3x32 nextpc(valP, valC, valM, pcsource, npc);
assign pcsource[0] = jmp | (je & zf) | (jne & ~zf) | (jg & (~sf & ~zf)) | (jge & (~sf | zf)) | (jl & (sf & ~zf)) | (jle & (sf | zf)) | call;
assign pcsource[1] = ret;
assign wmem = rmmovl | pushl | call;
assign wra = mrmovl | popl;
assign wrb = addl | subl | andl | xorl | rrmovl | irmovl;
assign wesp = pushl | popl | call | ret;
//mux4x32 alu_a (valA, valC, 32'h4, -32'h4, rasource, alua);
assign rasource[0] = irmovl | rmmovl | mrmovl | pushl | call;
assign rasource[1] = popl | ret | pushl | call;
//mux2x32 alu_b (valB, 32'h0, rbsource, alub);
assign rbsource = rrmovl | irmovl;
//4'bx001: s = a + b; //x001 ADDL
//4'bx010: s = a - b; //x010 SUBL
//4'bx011: s = a & b; //x011 ANDL
//4'bx100: s = a ^ b; //x100 XORL
assign aluc[2] = xorl | andl;
assign aluc[1] = subl | andl;
assign aluc[0] = addl | rrmovl | irmovl | rmmovl | mrmovl | pushl | popl | call | ret;
assign cc = (addl | subl | xorl | andl) & ~clock;
endmodule
//==================================================================================================
// Filename : stopwatch.v
// Created On : 2014-05-08 11:21:32
// Last Modified : 2014-05-28 20:01:40
// Revision :
// Author : larryxiao
// Description :
//
// This stopwatch is just to test the work of LED and KEY on DE1-SOC board.
// The counter is designed by a series mode. / asynchronous mode. 即异步进位
// use "=" to give value to hour_counter_high and so on. 异步操作/阻塞赋值方式
// 3 key: key_reset/系统复位, key_start_pause/暂停计时, key_display_stop/暂停显示
//
// ==============================================================
module stopwatch_01(clk,key_reset,key_start_pause,key_display_stop,
// 时钟输入 + 3 个按键;按键按下为 0 。板上利用施密特触发器做了一定消抖,效果待测试。
hex0,hex1,hex2,hex3,hex4,hex5,
// 板上的 6 个 7 段数码管,每个数码管有 7 位控制信号。
led0,led1,led2,led3 );
// LED 发光二极管指示灯,用于指示/测试程序按键状态,若需要,可增加。 高电平亮。
input clk,key_reset,key_start_pause,key_display_stop;
output [6:0] hex0,hex1,hex2,hex3,hex4,hex5;
output led0,led1,led2,led3;
reg led0,led1,led2,led3;
reg display_work;
// 显示刷新,即显示寄存器的值 实时 更新为 计数寄存器 的值。
reg counter_work;
// 计数(计时)工作 状态,由按键 “计时/暂停” 控制。
parameter DELAY_TIME = 1000000;
// 定义一个常量参数。 10000000 ->200ms;
// 定义 6 个显示数据(变量)寄存器:
reg [3:0] minute_display_high;
reg [3:0] minute_display_low;
reg [3:0] second_display_high;
reg [3:0] second_display_low;
reg [3:0] msecond_display_high = 1;
reg [3:0] msecond_display_low = 1;
// 定义 6 个计时数据(变量)寄存器:
// 定义 6 个显示数据(变量)寄存器:
reg [3:0] minute_counter_high;
reg [3:0] minute_counter_low;
reg [3:0] second_counter_high;
reg [3:0] second_counter_low;
reg [3:0] msecond_counter_high;
reg [3:0] msecond_counter_low;
reg [31:0] counter_50M; // 计时用计数器, 每个 50MHz 的 clock 为 20ns。
parameter COUNTCOUNT = 500000;
// DE1-SOC 板上有 4 个时钟, 都为 50MHz,所以需要 500000 次 20ns 之后,才是 10ms。
reg reset_1_time; // 消抖动用状态寄存器 -- for reset KEY
reg [31:0] counter_reset; // 按键状态时间计数器
reg start_1_time; //消抖动用状态寄存器 -- for counter/pause KEY
reg [31:0] counter_start; //按键状态时间计数器
reg display_1_time; //消抖动用状态寄存器 -- for KEY_display_refresh/pause
reg [31:0] counter_display; //按键状态时间计数器
reg start; // 工作状态寄存器
reg display; // 工作状态寄存器
// sevenseg 模块为 4 位的 BCD 码至 7 段 LED 的译码器,
//下面实例化 6 个 LED 数码管的各自译码器。
sevenseg LED8_minute_display_high( minute_display_high, hex5);
sevenseg LED8_minute_display_low( minute_display_low, hex4);
sevenseg LED8_second_display_high( second_display_high, hex3);
sevenseg LED8_second_display_low( second_display_low, hex2);
sevenseg LED8_msecond_display_high( msecond_display_high, hex1);
sevenseg LED8_msecond_display_low( msecond_display_low, hex0);
always @ (posedge clk) //每一个时钟上升沿开始触发下面的逻辑
begin
//此处功能代码省略,由同学自行设计。
msecond_display_low = 1;
// key_reset/系统复位, key_start_pause/暂停计时, key_display_stop/暂停显示
if (key_reset == 0)
begin
counter_reset = counter_reset + 1;
end
else
begin
counter_reset = 0;
end
if (key_start_pause == 0)
begin
counter_start = counter_start + 1;
end
else
begin
counter_start = 0;
end
if (key_display_stop == 0)
begin
counter_display = counter_display + 1;
end
else
begin
counter_display = 0;
end
if (counter_reset==DELAY_TIME)
begin
minute_display_high = 0;
minute_display_low = 0;
second_display_high = 0;
second_display_low = 0;
msecond_display_high = 0;
msecond_display_low = 0;
minute_counter_high = 0;
minute_counter_low = 0;
second_counter_high = 0;
second_counter_low = 0;
msecond_counter_high = 0;
msecond_counter_low = 0;
counter_50M = 0;
start = 0;
display = 0;
end
if (counter_start==DELAY_TIME)
begin
start = 1 - start;
end
if (counter_display==DELAY_TIME)
begin
display = 1 - display;
end
if (start == 1)
begin
counter_50M = counter_50M + 1;
// 10ms
if (counter_50M == COUNTCOUNT)
begin
counter_50M = 0;
msecond_counter_low = msecond_counter_low + 1;
if (msecond_counter_low == 10)
begin
msecond_counter_high = msecond_counter_high + 1;
msecond_counter_low = 0;
if (msecond_counter_high == 10)
begin
second_counter_low = second_counter_low + 1;
msecond_counter_high = 0;
if (second_counter_low == 10)
begin
second_counter_high = second_counter_high + 1;
second_counter_low = 0;
if (second_counter_high == 6)
begin
minute_counter_low = minute_counter_low + 1;
second_counter_high = 0;
if (minute_counter_low == 10)
begin
minute_counter_high = minute_counter_high + 1;
minute_counter_low = 0;
if (minute_counter_high == 6)
begin
minute_counter_high = 0;
end
end
end
end
end
end
end
end
if (display == 0)
begin
msecond_display_low = msecond_counter_low;
msecond_display_high = msecond_counter_high;
second_display_low = second_counter_low;
second_display_high = second_counter_high;
minute_display_low = minute_counter_low;
minute_display_high = minute_counter_high;
end
end
endmodule
//4bit 的 BCD 码至 7 段 LED 数码管译码器模块
module sevenseg(data, ledsegments);
input [3:0] data;
output ledsegments;
reg [6:0] ledsegments;
always @ (*)
case(data)
// gfe_dcba 7 段 LED 数码管的位段编号
// 654_3210 DE1-SOC 板上的信号位编号
0: ledsegments = 7'b100_0000; // DE1-SOC 板上的数码管为共阳极接法。
1: ledsegments = 7'b111_1001;
2: ledsegments = 7'b010_0100;
3: ledsegments = 7'b011_0000;
4: ledsegments = 7'b001_1001;
5: ledsegments = 7'b001_0010;
6: ledsegments = 7'b000_0010;
7: ledsegments = 7'b111_1000;
8: ledsegments = 7'b000_0000;
9: ledsegments = 7'b001_0000;
default: ledsegments = 7'b111_1111; // 其它值时全灭。
endcase
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment